You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地Tomcat正常的ServerEndpoint/WebSocket在Heroku上异常

Java WebSocket应用在Heroku部署后出现404错误排查

我有一个Java WebSocket应用,构造服务器端点URL的代码如下:

function constructWebSocket(endpoint, onMessageCallback) {

    const url = constructWebSocketUrl(endpoint);
    const socket = new WebSocket(url);

    socket.onopen = (event) => {
        console.log("onopen. Event: ", event);
    };

    socket.onmessage = onMessageCallback;
    socket.onclose = (event) => {
        console.log("onclose. Event: ", event);
    };

    socket.onerror = (event) => {
        console.log("onerror. Event: ", event);
    };

    return socket;
}

function constructWebSocketUrl(endpoint) {
    const host = document.location.host;
    const path = document.location.pathname;
    const protocol = document.location.protocol;
    
    if (protocol.startsWith("https")) {
        return `wss://${host}${path}${endpoint}`;
    } else if (protocol.startsWith("http")) {
        return `ws://${host}${path}${endpoint}`;
    } else {
        throw `Unknown protocol: ${protocol}.`;
    }
}

该应用已部署在Heroku上,本地Tomcat环境中能正常创建有效的WebSocket连接,但在Heroku上返回404 Not Found及关闭码1006。

日志信息

当尝试调用/randomize WebSocket端点时,日志中出现以下错误:

2024-04-12T10:31:55.096386+00:00 heroku[router]: at=info method=GET path="/randomize" host=wiki-game-killer-ae0862952895.herokuapp.com request_id=bd425c43-f582-4152-ad24-3f7ee429ca88 fwd="93.106.179.198" dyno=web.1 connect=0ms service=9ms status=404 bytes=854 protocol=https

问题原因与解决方案

1. 路径拼接错误(核心问题)

你的constructWebSocketUrl函数将当前页面的pathname与端点拼接,这会导致两个关键问题:

  • 如果用户访问根路径(/),拼接后会出现重复斜杠(比如wss://xxx.herokuapp.com//randomize),Heroku路由会识别为无效路径。
  • 如果WebSocket端点注册在应用根上下文下(比如Java代码中@ServerEndpoint("/randomize")),不需要带上页面的pathname,否则会请求错误的路径(比如页面路径是/app,就会请求/app/randomize,但端点实际在/randomize)。

修复代码:

function constructWebSocketUrl(endpoint) {
    const host = document.location.host;
    const protocol = document.location.protocol;
    const wsProtocol = protocol.startsWith("https") ? "wss" : "ws";
    
    // 标准化端点路径,确保开头只有一个斜杠
    const normalizedEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
    return `${wsProtocol}://${host}${normalizedEndpoint}`;
}

2. 验证WebSocket端点注册

检查Java代码中的@ServerEndpoint注解路径是否与请求路径一致。比如如果注解是@ServerEndpoint("/randomize"),正确的WebSocket URL应该是wss://xxx.herokuapp.com/randomize,不需要额外路径前缀。

3. 检查Heroku部署配置

  • 确认应用使用的Java版本支持WebSocket(Java 7及以上,推荐Java 8+)。
  • 查看应用启动日志,确保WebSocket端点已成功注册,无初始化错误。
  • 确认Heroku的Tomcat环境已启用WebSocket支持(默认启用,若自定义容器配置需额外验证)。

4. 用开发者工具确认请求URL

在浏览器开发者工具的Network标签中,查看WebSocket的请求地址,确认是否与预期端点路径一致,排查是否存在额外路径前缀或重复斜杠问题。


内容的提问来源于stack exchange,提问作者coderodde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:59:35