Websocket 在本地可以工作,但在 Heroku 上无法工作

8

我有一个应用程序,使用Spring作为后端,使用websockets(STOMP over SockJs)。在本地Tomcat上运行良好(WebSockets),但是当我部署到Heroku或AWS时,WebSockets停止工作。 我的Angular2中的websocket配置如下:

        let sockjs = new SockJS('/rest/add?jwt=' + this.authService.getToken(), {"devel":true,"debug":true}, {"transports":["websocket"]});

我也尝试了一下。
{"disabled_transports":["websocket"]}

但是两者都失败了。 web.xml
 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
     http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
     version="3.1">

<context-param>
    <param-name>spring.profiles.default</param-name>
    <param-value>default</param-value>
</context-param>

<servlet>
    <servlet-name>ws</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/spring/ws-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>ws</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/rest/*</url-pattern>

</filter-mapping>
</web-app>

Spring中的WebSocket

    <websocket:message-broker
    application-destination-prefix="/app">
    <websocket:stomp-endpoint path="/add">
        <websocket:sockjs/>
    </websocket:stomp-endpoint>
    <websocket:simple-broker prefix="/topic, /queue" />
</websocket:message-broker>

这是我在Heroku上的应用程序URL,你可以在Web浏览器的控制台中自己检查。 链接 请查看更新的日志,这段话让我感到担忧没有传输处理程序

CJyb2xlcyI6IkNVU1RPTUVSIn0.wFqNOduN-lD1-9GIRnG1X1aLJZTxtz9c6vmO7jmPPiE2017-04-06T16:23:32.439917+00:00 app[web.1]: 2017-04-06 16:2332 WARN  DefaultSockJsService:239 - No TransportHandler for http://myapp-ws.herokuapp.com/rest/add/097/eyocvxic/websocket?jwt=eyJhbGciOiJI

1
你的日志不相关,请检查Vegur日志 - 可能Vegur配置不正确并且会断开WebSocket连接。不要禁用WebSocket,你需要启用WebSocket。 - user1516873
我在日志中看到H27错误https://devcenter.heroku.com/changelog-items/662,但没有关于在Heroku上需要改变什么的信息(可能是因为我使用的是免费账户而不是付费账户引起的)。我还向Heroku支持团队提交了一张工单以便他们查看此问题。 - Lukasz
1
我不是Heroku专家。我猜你的连接被代理/负载均衡器断开了,但是很抱歉,我无法帮助你解决这个问题。 - user1516873
1
这个例子对我不起作用 - WebSocket 连接立即以 404 HTTP 状态断开。也许这是 Heroku 的问题。作为替代方案,可以尝试 OpenShift - 它声明支持 WebSockets 并提供免费计划。 - user1516873
1
http-session-affinity - 粘性会话的参数,用于负载均衡。如果您有至少两个实例的集群而不共享会话,则非常有用。例如 - 这里是Apache的配置,它作为代理和负载均衡器工作于2个Tomcat实例,只是为了说明复杂性https://dev59.com/CJffa4cB1Zd3GeqP-ZxR#42578769 Heroku使用Verur作为代理,应该具有类似的设置。 - user1516873
显示剩余4条评论
1个回答

11

好的,最终我成功了。结果发现Heroku上的Tomcat没有标准的库集合。首先我在本地部署在webapp-runner上https://devcenter.heroku.com/articles/java-webapp-runner之后,我看到一个奇怪的错误。我尝试了一些库,最终在添加了...

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
    <version>8.5.11</version>
</dependency>

<build>
...
<plugins>
    ...
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.3</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals><goal>copy</goal></goals>
                <configuration>
                    <artifactItems>
                        <artifactItem>
                            <groupId>com.github.jsimone</groupId>
                            <artifactId>webapp-runner</artifactId>
                            <version>8.5.11.3</version>
                            <destFileName>webapp-runner.jar</destFileName>
                        </artifactItem>
                    </artifactItems>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

我已经在本地将其运行起来了。 然后我添加了以下内容的PROCFILE

web:    java $JAVA_OPTS -jar myapp-ws/target/dependency/webapp-runner.jar --port $PORT myapp-ws/target/*.war

我已经将git与Heroku集成,并承诺使用GITHUB,从Heroku内触发构建并运作正常。


提升一下,因为你不仅解决了自己的问题,还在这里留下了答案,方便下一个程序员。 - Richard_G
感谢Lukasz。现在我们是否仍需要“webapp-runner”和“tomcat-embed-websocket”来利用Heroku上的Websockets?我正在将webapp-runner升级到8.5.27.0版本。但是,如果我们可以直接在Heroku部署的Tomcat上运行应用程序,则更好。 - Thang Le
当您将应用程序移到Spring Boot并将其作为jar运行时,webapp-runner和tomcat-embed-websocket都是多余的。 - Lukasz
是的,我仍在使用Spring classic。但我认为tomcat 8.5.30已经集成了tomcat-websocket.jar,所以现在不需要请求:<artifactId>tomcat-embed-websocket</artifactId>,但当然仍然需要webapp-runner 8.5.30。无论如何,谢谢。 - Thang Le

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接