EJB Websocket握手错误:响应代码不是101:404

问题描述

如果您没有时间阅读详细信息,那么我的总结问题是:

一个简单的websocket请求通过 EJB Websocket Endpoint Server

发送到ejb module时,我收到Http错误代码404

(由maven使用Java8,EJB3和JBOSS EAP 7.2创建的项目)

请注意,ejb模块不能既没有 web.xml 也没有 maven contextRoot tag

详细信息:

我用EJB3开发了一个企业项目,并使用IntellijIdea中的maven通过JBOSS-EAP7.2进行了部署。 我需要提供一个websocket服务器和客户端以与第三方进行通信。提供的一些代码如下:

服务器端:

@ServerEndpoint("/chat")
public class ChatServer {
    private Session session;

    @Onopen
    public void connect(Session session){
        this.session=session;
    }

    @OnClose
    public void close(){
        this.session=null;
    }
    
    @OnMessage
    public void processMessage(String msg){
        System.out.println("msg = " + msg);;
        if(this.session!=null && this.session.isopen()){
            try {
                this.session.getBasicRemote().sendText("this is from server");
            } catch (IOException e) {
                e.printstacktrace();
            }
        }
    }
}

在服务器上,我们也拥有此类来声明根路径(并启用我们的JAX-RS):

@ApplicationPath("gateway")
public class RestApplication extends Application {
    // without any implementation
}

此外,我在服务器端有一个过滤器,如下所示,该过滤器对websocket请求不执行任何操作,并且在调试时显示该请求是在过滤器处接收到的,但是在服务器生成400且请求从未发送到ServerEndpoint之后!

HTTP过滤器:

@Provider
@PreMatching
public class SecurityFilter implements ContainerRequestFilter,ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
    //some snipet to evaluate the JAX-RS and nothing to do with websocket requests
    //websocket request received here but it did not go toward EndpointServer
    }

    @Override
    public void filter(ContainerRequestContext containerRequestContext,ContainerResponseContext containerResponseContext) throws IOException {
        System.out.println("response status: "+ containerResponseContext.getStatus());
        //here I get Http status code 404 
    }
}

删除了过滤器,但错误仍然存​​在。

客户端

public class SocketSmokeTest {
    private WebSocketContainer container;
    private HelloEndpoint endpoint;

    @Test
    public void communicate() {
        try {
            Session connectToServer = container.connectToServer
            (this.endpoint,new URI("ws://127.0.0.1:8080/gateway/chat"));
            //I have tried other path like "ws://127.0.0.1:8080/rootsource/gateway/chat"
            //or "ws://127.0.0.1:8080/rootsource/chat"
            this.endpoint.sendMessage("hello from client");
            Thread.sleep(3000);
        } catch (URISyntaxException e) {
            e.printstacktrace();
        } catch (DeploymentException e) {
            e.printstacktrace();
        } catch (IOException e) {
            e.printstacktrace();
        } catch (InterruptedException e) {
            e.printstacktrace();
        }
    }
}

HelloEndPoint一个简单的类,如下所示:

public class HelloEndpoint extends Endpoint {
    private Session session;

    @Override
    public void onopen(Session session,EndpointConfig endpointConfig) {
        this.session = session;

        this.session.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String message) {
                System.out.println("!!!!!!  retrieved message: " + message);
            }
        });
    }

    public void sendMessage(String message){
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printstacktrace();
        }
    }
}

错误:运行SmokeTest会收到此错误

javax.websocket.DeploymentException:握手错误

原因:org.glassfish.tyrus.core.HandshakeException:响应代码不是101:404。

wireshark捕获的数据:

GET /resources/websocket/chatserver/ HTTP/1.1
Connection: Upgrade
Host: 127.0.0.1:8080
Origin: http://127.0.0.1:8080
Sec-WebSocket-Key: K3mTSnyiVbi5/yeyIwFR2Q==
Sec-WebSocket-Version: 13
Upgrade: websocket

HTTP/1.1 404 Not Found
Connection: keep-alive
Content-Length: 0
Date: Sat,05 Sep 2020 05:02:43 GMT

有关项目结构的更多信息: 项目由多层方法中的一些模块组成,例如数据(ejb模块),业务(ejb模块),网关(ejb模块),GUI(war模块),这些模块聚集在EAR中。所有的JAX-RS和Websocket都驻留在网关模块中。

EAR pom文件

...
<dependencies>
    ...
</dependencies>
<build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <defaultLibBundleDir>lib</defaultLibBundleDir>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                    <modules>
                        <ejbModule>
                            <groupId>ir.co.isc</groupId>
                            <artifactId>BusinessLayer</artifactId>
                        </ejbModule>
                        <ejbModule>
                            <groupId>ir.co.isc</groupId>
                            <artifactId>DataAccessLayer</artifactId>
                        </ejbModule>
                        <ejbModule>
                            <groupId>ir.co.isc</groupId>
                            <artifactId>PresentationLayerGateway</artifactId>
                        </ejbModule>
                        <webModule>
                            <groupId>ir.co.isc</groupId>
                            <artifactId>PresentationLayerGUI</artifactId>
                            <contextRoot>/rootsource</contextRoot>
                        </webModule>
                    </modules>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
...

网关EJB模块pom文件

<?xml version="1.0" encoding="UTF-8"?>

<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>Azmoonyar</artifactId>
        <groupId>ir.co.isc</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>PresentationLayerGateway</artifactId>
    <packaging>ejb</packaging>

    <name>PresentationLayerGateway</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>ir.co.isc</groupId>
            <artifactId>BusinessLayer</artifactId>
            <version>1.0</version>
            <type>ejb</type>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>8.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.ejb/ejb-api -->
        <dependency>
            <groupId>javax.ejb</groupId>
            <artifactId>ejb-api</artifactId>
            <version>3.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-client-api</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.tyrus</groupId>
            <artifactId>tyrus-client</artifactId>
            <version>1.17</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.tyrus.bundles</groupId>
            <artifactId>tyrus-standalone-client</artifactId>
            <version>1.17</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-ejb-plugin</artifactId>
                    <version>3.1.0</version>
                    <configuration>
                        <ejbVersion>3.0</ejbVersion>
                        <archive>
                            <manifest>
                                <addClasspath>true</addClasspath>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version   >
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>3.0.0-M3</version>
                    <configuration>
                        <skipTests>${skipTests}</skipTests>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)