Programmatic ServerEndpoint не будет работать во встроенном Tomcat - PullRequest
0 голосов
/ 26 ноября 2018

У меня работает встроенный tomcat, и я пытаюсь настроить веб-сокеты программно, не могу использовать аннотации, так как я получаю список контекстных путей динамически.Использование Java 8 и Tomcat 7.

Ниже приведен код, который я использую,

Embedded Tomcat,

public class EmbeddedTomcat {
/**
 * @param args
 * @throws LifecycleException 
 */
public static void main(String[] args) throws LifecycleException {
    Tomcat tomcat = new Tomcat();
    tomcat.setPort(5555);

    Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());

    Tomcat.addServlet(ctx, "hello", new HttpServlet() {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) 
                throws ServletException, IOException {
            Writer w = resp.getWriter();
            w.write("Hello World !!");
            w.flush();
            w.close();
        }
    });

    ctx.addServletMapping("/hello", "hello");

    ctx.addApplicationListener(WSContextListener.class.getName());

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

}

WebSocket Listener для динамического прослушиваниядобавьте конечные точки,

public class WSContextListener extends WsContextListener {

@Override
public void contextInitialized(ServletContextEvent sce) {
    super.contextInitialized(sce);

    ServerContainer sc =
            (ServerContainer) sce.getServletContext().getAttribute(
                    Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
    try {
        ServerEndpointConfig endPointConfig = ServerEndpointConfig.Builder
                .create(WSEndpoint.class, "/wshello")
                .build();
        sc.addEndpoint(endPointConfig);
    } catch(DeploymentException de) {
        de.printStackTrace();
    }
}

}

Фактический класс конечных точек сервера,

public class WSEndpoint extends Endpoint {

/* (non-Javadoc)
 * @see javax.websocket.Endpoint#onOpen(javax.websocket.Session, javax.websocket.EndpointConfig)
 */
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
    System.out.println(String.format("Opened a new session with Id[%s] associated to endpoint[%s]", session.getId(), session.getRequestURI().getPath()));

    session.addMessageHandler(new MessageHandler.Whole<String>() {
        @Override
        public void onMessage(String data) {
            System.out.println("Data received - " + data);
            session.getAsyncRemote().sendText(data);
        }
    });
}

@Override
public void onClose(Session session, CloseReason closeReason) {
    System.out.println(String.format("Closing the connection to endpoint[%s] for session Id[%s] ", session.getRequestURI().getPath(), session.getId()));
    super.onClose(session, closeReason);
}

@Override
public void onError(Session session, Throwable throwable) {
    System.out.println(String.format("Error [%s] occurred on session Id[%s] associated to endpoint[%s]", throwable.getMessage(), session.getId(), session.getRequestURI().getPath()));
    super.onError(session, throwable);
}

}

Наконец, бит javascript для подключения квеб-сокет,

var webSocket = new WebSocket("ws://localhost:5555/wshello");

Я могу получить доступ к сервлету (http://localhost:5555/hello), и этот бит работает. В тот момент, когда я пытаюсь получить доступ к веб-сокету через приведенный выше код javascript, он завершается с ошибкой,

websocket_test.html: 18 Сбой подключения WebSocket к 'ws: // localhost: 5555 / wshello': Ошибка при рукопожатии WebSocket: Неожиданный код ответа: 404

1 Ответ

0 голосов
/ 26 ноября 2018

Попробуйте это

var webSocket = new WebSocket("ws://localhost:5555/hello", "protocol");

Протокол, добавленный для обработки веб-сокета на стороне клиента (необязательно).Удалить wshello "ws"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...