JBoss 上带有 SockJS 的 Spring-MVC Websocket:如果没有 IO 事件,无法从 HTTP/1.1 升级

Posted

技术标签:

【中文标题】JBoss 上带有 SockJS 的 Spring-MVC Websocket:如果没有 IO 事件,无法从 HTTP/1.1 升级【英文标题】:Spring-MVC Websockets with SockJS on JBoss: Cannot upgrade from HTTP/1.1 without IO events 【发布时间】:2015-02-03 20:25:15 【问题描述】:

我的目标:当特定事件发生时,我想在我的页面上向所有客户广播一条消息。这可能会在 15 秒内发生。

我想使用 Websockets,目前它看起来很不错。在观看了不同的演讲并阅读了多个项目声明和官方文档之后,我认为我得到了交易。

但是,我被这个错误消息卡住了,我不知道该怎么办了:

JBWEB000034: Cannot upgrade from HTTP/1.1 without IO events

设置:

春季版 4.1.1 JBoss EAP 6.3 IntelliJ 马文

我将转储我所有的配置和代码的当前状态:

WebsocketController

@Controller
public class WebsocketController extends TextWebSocketHandler

    @MessageMapping
    @SendTo("/topic/nextImg")
    public Message nextImg() 
        return new Message("next");
    

消息(简单 DTO)

public class Message 
    private String message;

    public Message(String message) 
        this.message = message;
    

    public String getMessage() 
        return message;
    

mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:websocket="http://www.springframework.org/schema/websocket"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
        http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd">

    <context:component-scan base-package="global.pics"/>
    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="multipartResolver"
                class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

        <!-- setting maximum upload size -->
        <property name="maxUploadSize" value="10000000" />

    </bean>

    <bean id="websocketController" class="global.pics.websocket.WebsocketController"/>

    <websocket:handlers>
        <websocket:mapping path="/next" handler="websocketController"/>
        <websocket:sockjs/>
    </websocket:handlers>


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


    <mvc:resources mapping="/resources/**" location="/resources/" />

    <task:scheduled-tasks>
        <task:scheduled ref="queueController" method="nextImg" fixed-rate="13370"/>
    </task:scheduled-tasks>

    <task:scheduled-tasks>
        <task:scheduled ref="imageCounter" method="backup" fixed-delay="60000"/>
    </task:scheduled-tasks>

</beans>

web.xml

<web-app version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>share.pics.global</display-name>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>



<!--update: context-param-->

<context-param>
    <param-name>websockets-enabled</param-name>
    <param-value>true</param-value>
</context-param>

</web-app>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.springapp</groupId>
    <artifactId>picsglobal</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>picsglobal</name>

    <properties>
        <spring.version>4.1.1.RELEASE</spring.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.1.10.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>$spring.version</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>$spring.version</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>$spring.version</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>$spring.version</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.spec.javax.websocket</groupId>
            <artifactId>jboss-websocket-api_1.1_spec</artifactId>
            <version>1.1.1.Final</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.1</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>1.2.1.RELEASE</version>
        </dependency>


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <!--update: looks like this is nescessary for whatever reason-->

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-spring</artifactId>
            <version>3.0.10.Final</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>picsglobal</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>**/*Tests.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
        <repository>
            <id>central</id>
            <url>http://repo1.maven.org/maven/</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>

</project>

如果我错过了什么,你可以在我的 Github 上找到所有内容: https://github.com/r79/picsglobal

我希望有人能够帮助我。这件事变得非常令人沮丧,即使我没有做任何示例而只是试图用它来构建一些东西,这在某种程度上是我的错。

更新:

我在 web.xml 中添加了上下文参数(见上文)。看起来 spring-web.xml 已被弃用,带有 context-param 的解决方案是更新的表单。

我还在 pom.xml 中添加了以下依赖项。

我目前正在使用最新的 Wildfly-Alpha (9.0.0),因为看起来当前的生产版本在 spring 中存在错误:https://issues.jboss.org/browse/WFLY-3439

但是,我仍然收到错误消息。如果我找到解决方案,我正在尝试修复这些问题并更新此线程。对于遇到问题的其他人来说,一个可能的快速修复可能是切换到 Tomcat,它似乎在那里工作。我必须先尝试用 Wildfly 运行它,因为我在 JBoss 上使用了一些依赖项。

更新:

看起来我试图让这个东西工作的最新 WildFly (9.0.0.alpha1) 有另一个 Spring 错误:[无法发布第二个链接,因为我在这里的声誉很低,谷歌为“wildfly 9 getresteasyspringvirtualfile” ,这是那里的第一个链接]

看起来他们将请求拉入了他们的开发分支,但我无法在没有错误的情况下构建它。在这一点上,我停止尝试让它与 wildfly 一起工作并切换到 Tomcat。

解决方案是等待一个没有 bug 的 WildFly 环境或只使用 Tomcat。一旦我设法让这个东西在 Tomcat 上运行,我就会回答这个问题。

【问题讨论】:

请看这里:***.com/questions/24016996/… @ArtemBilan 已经找到了这个。关于这个问题的唯一答案,第一个链接是死的,第二个链接是指文档,只告诉我支持 undertow 1.0(JBoss 使用)。关于如何使用 jboss-web.xml 的搜索仅参考了官方文档,没有关于如何绑定它的示例。如果有人能够解释那是什么以及如何将它绑定到它可能会有所帮助。跨度> 我想你的意思是这个github.com/jboss-developer/jboss-eap-quickstarts/tree/… @ArtemBilan 非常感谢。现在看起来该示例无法正常工作。 xml 位置似乎有问题(启动时出现基本错误消息):消息:遇到意外元素“jboss.com/xml/ns/javaeeenable-websockets'” 你能用那个 jboss-web.xml 文件更新你的问题吗 【参考方案1】:

我认为你在这里混合了三个问题。

JBoss EAP 6.3 上的“无法在没有 IO 事件的情况下从 HTTP/1.1 升级”

这通常意味着您忘记在配置中激活“启用 websockets”。 “jboss-web.xml”文件现在可能已被弃用,但不适用于该 JBoss 版本。

Wildfly 8.2 和 WFLY-3439

这并没有说明它与 Spring 相关的任何地方。你能详细说明一下吗?你遇到过这个问题吗?

野蝇 9.0.0.alpha1

Wildfly 9.0/undertow 1.2 目前不受 Spring 官方支持(但它们现在可能开箱即用) - 请关注 SPR-12469 并在此处报告问题(如果有任何问题)。

【讨论】:

不推荐使用“jboss-web.xml”。请关注:github.com/burrsutter/simplechat 和最新文档:access.redhat.com/documentation/en-US/…。

以上是关于JBoss 上带有 SockJS 的 Spring-MVC Websocket:如果没有 IO 事件,无法从 HTTP/1.1 升级的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Websockets 4.2 中使用 SockJS 的部分消息

没有 SockJS/StompJS 的 Spring STOMP 服务器

Spring WebSocket 使用 SockJS 连接到不同的域

订阅不工作 Spring SockJs Stomp

带有 websocket 和 stockjs 的 JBOSS eap 6.3 beta - 使用 spring 框架的 stomp.js

Spring 和 SockJs 的控制器组件问题