我使用spring实现了以下Web-Socket-Server。我们不想使用STOMP和JSocks。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebSocketServerHandler(), "/websocket/user/{userId}");
}
}
@Service
public class WebSocketServerHandler extends TextWebSocketHandler {
private List<WebSocketSession> sessions = new ArrayList<WebSocketSession>();
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws Exception {
session.sendMessage(message);
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.add(session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions = null;
}
}
现在我可以从前端客户端(浏览器)成功连接到该Web-Socket-Server。现在我想在运行时从我的一些java类连接到那个Web-Socket-Server,然后想要向该Web-Socket-Server发送消息。任何人都知道我该怎么办?
我添加了一个测试Rest Controller,如下所示:
@RequestMapping(value = "/web-socket/message/{message}")
public void sendMessage(@PathVariable("message") final String message) throws Exception {
final String WS_URI = "ws://localhost:8080/web-socket/user/23";
final CountDownLatch latch = new CountDownLatch(1);
WebSocketClientHandler handler = new WebSocketClientHandler(latch);
WebSocketClient client = new StandardWebSocketClient();
WebSocketSession session = client.doHandshake(handler, WS_URI).get();
session.sendMessage(new TextMessage(message));
latch.await(5, TimeUnit.SECONDS);
session.close();
}
我成功地能够向websocket服务器发送消息,只是第一次通过使用谷歌休息客户端调用此测试RestController。如果我需要再次发送消息,那么我必须重新启动tomcat服务器。我在这里做的有什么不对吗?
答案 0 :(得分:4)
spring-websocket
具有WebSocket客户端支持。基本合同是WebSocketClient
。 Spring并没有实现整个WebSocket支持,但提供了一个覆盖其他实现的抽象层。常见的Spring客户端抽象是StandardWebSocketClient
。一个简单的例子看起来像
public static void main(String... args) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
EchoHandler handler = new EchoHandler(latch);
WebSocketClient client = new StandardWebSocketClient();
WebSocketSession session = client.doHandshake(handler, ECHO_URL).get();
session.sendMessage(new TextMessage("Hello World"));
latch.await(5000, TimeUnit.SECONDS);
session.close();
}
EchoHandler
是客户端WebSocketHandler
(与服务器端相同)。
public class EchoHandler extends TextWebSocketHandler {
private final CountDownLatch latch;
public EchoHandler(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
System.out.println("------- received client message ------");
System.out.println(message.getPayload());
System.out.println("--------- end client message ---------");
latch.countDown();
}
}
如果在String环境中运行客户端,也可以将WebSocketClient
包装在WebSocketConnectionManager
中。如果需要,这将为您提供一些生命周期助手。请参阅Spring Boot sample中的示例。
就像我说的那样依赖于依赖关系,Spring并没有实现整个WebSocket客户端支持,所以你需要一个实现。如果您在支持WebSocket的服务器中运行客户端,则无需添加任何内容。支持实现应该已经在服务器的类路径中。主要支持的WebSocket实现是Jetty,Tomcat,Undertow(主要是Wildfly或独立的Undertow),Tyrus(即Glassfish,WebLogic)。
如果您在独立应用程序中运行客户端,则需要添加WebSocket实现。不幸的是,根据我的测试,没有一个实现提供完整可行的&#34;仅客户端&#34;罐。他们要么已经或已经完成了(包括服务器)实现。因此,仅使用客户端,仍然需要拉入一堆服务器罐。这是我从测试中得出的结果
所有
共同<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>${websocket.version}</version>
</dependency>
<强> Tomcat的强>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<强>暗流强>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>${undertow.version}</version>
</dependency>
<强>泰鲁斯强>
<!-- tyrus-client is pulled in by this. -->
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-server</artifactId>
<version>${tyrus.version}</version>
</dependency>
<强>码头强>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<version>${jetty.version}</version>
</dependency>
使用Jetty,它不使用标准的Java WebSocket API,因此StandardWebSocketClient
中没有使用它。你需要做的是
JettyWebSocketClient client = new JettyWebSocketClient();
client.start();
上面的其他所有内容都是相同的。
我只是看了一下Spring源代码,看看他们使用的所有不同依赖项。您可以查看它并使用依赖项。也许有更多有效(更轻)的依赖关系组合仍然有效。以上就是我测试过的,并且能够开始工作。