如果您没有时间阅读详细信息,那么我的总结问题是:
EJB Websocket Endpoint Server
ejb module
时,我收到Http错误代码404
请注意,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>