Javax WebSockets не будет работать с программной реализацией Tomcat 7 - PullRequest
0 голосов
/ 25 апреля 2018

Вот что я пытаюсь сделать:

  • Программно настроить сервер Tomcat 7 - работает с простым сервлетом.Я определяю конечные точки Tomcat только из кода, в файловой системе нет ни настроек, ни маршрутизаторов (это ограничение).
  • Пусть указанный сервер Tomcat включает конечную точку сервера websocket с использованием API Javax Websockets (1.1) - не работает .

Моя точка входа приложения / сервера:

package com.myapp;

import java.io.File;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.FilterMap;
import org.apache.catalina.startup.Tomcat;

public class App 
{
    public static void main(String[] args) throws LifecycleException
    {
        int port = 8080;

        Tomcat webServer = new Tomcat();

        webServer.setPort(port);
        webServer.setHostname("localhost");
        String appBase = ".";
        webServer.getHost().setAppBase(appBase);
        File docBase = new File(System.getProperty("java.io.tmpdir"));
        Context context = webServer.addContext("", docBase.getAbsolutePath());

        // both MyServlet and MyFilter exist and work.
        Class servletClass = MyServlet.class;

        Tomcat.addServlet(context, servletClass.getSimpleName(), servletClass.getName());
        context.addServletMapping("/my-servlet/*", servletClass.getSimpleName());

        Class filterClass = MyFilter.class;
        FilterDef myFilterDef = new FilterDef();
        myFilterDef.setFilterClass(filterClass.getName());
        myFilterDef.setFilterName(filterClass.getSimpleName());
        context.addFilterDef(myFilterDef);

        FilterMap myFilterMap = new FilterMap();
        myFilterMap.setFilterName(filterClass.getSimpleName());
        myFilterMap.addURLPattern("/my-servlet/*");
        context.addFilterMap(myFilterMap);

        webServer.start();
        webServer.getServer().await();
    }
}

Класс конечной точки моего сервера веб-сокетов:

package com.myapp;

import java.nio.ByteBuffer;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.PongMessage;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/web-socket/")
public class WebSocket
{

    @OnOpen
    public void onOpen()
    {
        System.out.println("Open Connection ...");
    }

     @OnMessage
    public static  void onTextMessage(Session session, String msg) {
        System.out.println("On Message for Web Socket");
    }   
    @OnMessage
    public void onBinaryMessage(Session session, ByteBuffer msg){
        System.out.println("On Message for Web Socket");
    }   
    @OnMessage
    public void onPongMessage(Session session, PongMessage pMsg) {
        System.out.println("On Message for Web Socket");
    }
    @OnClose
    public void onClose(Session session) {
        System.out.println("Connection Close for Web Socket");
    }

    @OnError
    public void onError(Throwable e)
    {
        e.printStackTrace();
    }
}

Я использую Maven, и я включаю API WebSocket с <scope>provided</scope>, как я видел в других вопросах, что это было причиной других проблем.

Когда я запускаюсервер, я могу успешно подключиться к конечной точке my-servlet (как веб-страница, конечно), но когда я пытаюсь создать объект WS, просто в консоли разработчика браузера, используя var webSocket = new WebSocket("ws://localhost:8080/web-socket"), он говорит, что не можетпоразить конечную точку:

WebSocket connection to 'ws://localhost:8080/web-socket' failed: Error during WebSocket handshake: Unexpected response code: 404

Мой вопрос: Что мне не хватает? Сообщение об ошибке (из Chrome) говорит о том, что конечная точка не зарегистрирована (отсюда и 404).Как зарегистрировать веб-сокет ServerEndpoint?Спасибо!

РЕДАКТИРОВАТЬ:

Вот моя реализация MyServlet класса:

package com.myapp;

import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet
{

    @Override
    protected void doGet(
            HttpServletRequest req,
            HttpServletResponse resp) throws IOException
    {

        resp.setStatus(HttpServletResponse.SC_OK);
        resp.getWriter().write("Works...");
        resp.getWriter().flush();
        resp.getWriter().close();
    }

}

А вот моя реализация MyFilter:

package com.myapp;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class MyFilter implements Filter
{

    @Override
    public void init(FilterConfig filterConfig)
    {
        // ...
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {

        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.addHeader("myHeader", "myHeaderValue");
        chain.doFilter(request, httpResponse);
    }

    @Override
    public void destroy()
    {
        // ...
    }
}

1 Ответ

0 голосов
/ 26 апреля 2018

Попробуйте добавить вручную конечную точку веб-сокета:


    String serverContainerClass = ServerContainer.class.getName();
    //should be "javax.websocket.server.ServerContainer", if not, some external package could have hogged the implementation
    final ServerContainer serverContainer = (ServerContainer) context.getServletContext().getAttribute(serverContainerClass);
    try 
    {
        serverContainer.addEndpoint(WebSocket.class);
    } 
    catch (DeploymentException e)
    {
        TraceWriter.Error(this, "Failed to initialize websocket", e);
    }

Вы должны поместить этот код после добавления сервлета в контекст

...