当前位置: 首页 > 知识库问答 >
问题:

在运行时从后端java类连接到Web-Socket-Server

东方俊杰
2023-03-14

我已经使用spring实现了以下Web套接字服务器。我们不想使用STOMP和jsock。

@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套接字服务器。现在,我想在运行时从一些java类连接到该Web套接字服务器,然后向该Web套接字服务器发送消息。有人知道我该怎么做吗?

我添加了一个测试Rest控制器如下:

 @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服务器,这是我第一次使用google rest客户端调用这个Test RestController。如果我需要再次发送消息,那么我必须重新启动tomcat服务器。我在这里做的有什么不对吗?

共有1个答案

越高峻
2023-03-14

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();
    }
}

如果在字符串环境中运行客户端,还可以将WebSocketClient包装在WebSocketConnectionManager中。如果您需要,这将为您提供一些生命周期帮助。参见Spring Boot示例中的示例。

就依赖关系而言,正如我所说,Spring并没有实现整个WebSocket客户端支持,所以您需要一个实现。如果在支持WebSocket的服务器上运行客户机,则无需添加任何内容。支持实现应该已经位于服务器的类路径上。主要支持的WebSocket实现有Jetty、Tomcat、Undertow(主要是Wildfly或独立Undertow)、Tyrus(即Glassfish、WebLogic)。

如果在独立应用程序中运行客户端,则需要添加WebSocket实现。不幸的是,根据我的测试,没有一个实现提供了一个完全可行的“仅客户端”jar。它们要么需要,要么已经引入了完整的(包括服务器)实现。因此,仅使用客户机仍然需要引入大量服务器jar。以下是我通过测试得出的结论

共同的

<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>

公猫

<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源代码,以查看它们使用的所有不同依赖项。您可以查看它,并处理依赖项。也许还有其他更有效(更轻)的依赖项组合仍然有效。以上就是我测试过的,并且能够开始工作。

 类似资料:
  • 我有一个项目,在java 7运行时环境中,使用app engine,同时使用前端和后端实例(https://cloud.google.com/appengine/docs/standard/java/modules/converting) 我们现在想迁移到java 8运行时,但是我找不到在这种环境中迁移后端模块/服务的方法。因为java 8中不支持基于EAR的结构,如下面链接的第一段所述https

  • 问题内容: 我使用的是大猩猩网络套接字,我想在本地运行它,是指使用以下chrome客户端或其他推荐的工具……当我进入调试模式时,出现错误 我用 当我在Chrome或网络套接字客户端中运行以下网址时,出现错误 websocket:不是websocket握手:在“连接”标头中找不到“升级”令牌 我想运行它 并为本地模拟提供令牌,我该怎么做? 要检查它,我使用Chrome的Simple WebSocke

  • 大家好,我有一个简单的问题,如何在后台连续运行android中的一些代码块, 情况是检查互联网是否连接,相应地,它会将文件上传到服务器上。(这将在后台连续运行。) 我得到了类似BroadcastReceiver的东西,但我认为这只是为了检查互联网连接。 如果有人给块代码,让我明白,会有很大帮助... 谢谢

  • 在此之前,我的应用程序总是编译和执行。我只是使用 运行时位于C:/Program Files/java和JAVA_HOME**上 这个应用程序来自TextPad,它使用类路径运行良好,执行良好。系统编译正常,但我的JAR文件无法执行 问题:它无法在运行时找到我的类路径(它在编译时工作得很好),给了我这个错误 类路径 .;C:\Program Files(x86)\java\jre7\lib\ext

  • 问题内容: 我正在尝试使用gcloud beta仿真器中的bigtable仿真器。我启动模拟器,获取主机名(localhost)和端口(在本例中为8885) gcloud beta模拟器bigtable启动 执行中:/ usr / local / Caskroom / google-cloud-sdk / latest / google-cloud-sdk / platform / bigtabl

  • 我正在尝试将我的Java web项目连接到Firebase,这样我就可以将数据存储在FireStore中。我正在使用Java管理SDK,遵循官方指南:FireBaseAdminSDK。不幸的是,在初始化FirebaseAp时,我遇到了异常: 现在,我读到这里和那里,它的问题与guava项目,建议使用不同版本的guava库。我试过从18开始的所有版本。 我甚至下载了google firebase s