1

我正在尝试使用 websockets,所以我创建了这样的 WS 服务器:

@ServerEndpoint(value = "/chat")
public class WsChatServlet{
private static final Logger LOGGER =
        Logger.getLogger(WsChatServlet.class.getName());

@OnOpen
public void onOpen(Session session) {
    LOGGER.log(Level.INFO, "New connection with client: {0}",
            session.getId());
}

@OnMessage
public String onMessage(String message, Session session) {
    LOGGER.log(Level.INFO, "New message from Client [{0}]: {1}",
            new Object[] {session.getId(), message});
    return "Server received [" + message + "]";
}

@OnClose
public void onClose(Session session) {
    LOGGER.log(Level.INFO, "Close connection for client: {0}",
            session.getId());
}

@OnError
public void onError(Throwable exception, Session session) {
    LOGGER.log(Level.INFO, "Error for client: {0}", session.getId());
}
}

并将其部署在运行在 Java 7 上的 Tomcat 7 中。然后我创建了该客户端:

@ClientEndpoint
public class Main {
private static final String uri = "ws://myserver.net/chat";

public static void main(String[] args) throws DeploymentException, IOException, URISyntaxException, InterruptedException {
    WebSocketContainer wsContainer =  ContainerProvider.getWebSocketContainer();
    Session session = wsContainer.connectToServer(Main.class, new URI(uri));
    session.getBasicRemote().sendText("Here is a message!");
    Thread.sleep(1000);
    session.close();
}

@OnMessage public void processMessage(String message){
    System.out.println(message);
}
}

此客户端作为命令行应用程序运行。当我运行它时,我得到异常:

Exception in thread "main" javax.websocket.DeploymentException: The HTTP response from the server [HTTP/1.1 302 Found] did not permit the HTTP upgrade to WebSocket

所以看起来服务器没有正确响应我的客户。我注意到,如果我访问ws://myserver.net/chat,它会以 302 响应,但对于ws://myserver.net/chat/(注意/)它会以 200 OK 响应。

更有趣的是这个 Tomcat 日志:

    • [01/Oct/2014:15:52:35 +0000]“GET /chat/HTTP/1.0”200 57
    • [01/Oct/2014:15:52:42 +0000]“GET /chat HTTP/1.0”302 -

如您所见,我的客户端连接的是 HTTP 1.0,而不是 1.1,这可能是错误的。我完全被它困住了。不明白为什么它不起作用。

编辑: 所以,我的主要问题是为什么 websockets 不起作用(我猜 HTTP 升级响应标头丢失了)以及如何解决这个问题。

EDIT2: 我忘记了最重要的事情:我将它部署在免费的 Jelastic 环境中。

4

2 回答 2

3

所以最后我发现了问题所在,答案是:Jelastic。我将我的应用程序部署到了免费的 Jelastic 实例,这意味着所有请求都由 nginx 代理。如此处所述,您必须获取公共 IP 才能让您的应用程序在 Jelastic 中使用 WebSockets。

于 2014-10-02T14:23:05.337 回答
0

如维基百科所述:

HTTP 响应状态码 302 Found 是执行 URL 重定向的常用方式

那 200 OK 是

成功 HTTP 请求的标准响应

因此,根据您的情况,我猜您的资源管理器正在使用尾部斜杠保存第一个请求,无论哪种情况,http 状态都是 Found 或 OK,资源已找到。

最后我想将sessionCookiePathUsesTrailingSlash的值更改为 false 可以解决问题,并且响应将始终为 200 OK。(为了改变它检查这个

如果这不起作用,有很多原因可以推动 tomcat 添加斜杠,其他原因请查看此讨论

于 2014-10-01T20:20:43.963 回答