0


SpringBoot集成websocket作为客户端和服务端的代码案例

websocket介绍:

WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许服务端和客户端之间进行实时、双向的数据传输。

  • 长连接:WebSocket建立连接后,只要不关闭,会一直保持连接状态,使得服务器可以主动向客户端推送数据。
  • 双向通信:与HTTP请求-响应模式不同,WebSocket支持双向通信,即客户端和服务端都可以发送或接收数据。

使用场景:

在需要实时交互的场景中使用,例如聊天应用,实时数据推送,内容流式输出等。可实现实时向客户端进行数据推送。

1、SpringBoot集成websocket作为服务端

在前后端分离的项目中,前端作为websocket的客户端,后端服务作为websocket的服务端。

实现步骤:

  1. 添加websocket整合包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
  2. 编写websocket配置类,暴露WebSocket@ConfigurationpublicclassWebSocketConfig{@BeanpublicServerEndpointExporterserverEndpointExporter(){returnnewServerEndpointExporter();}}
  3. 编写websocket服务监听程序及处理逻辑packagecom.houdehong.wsserver.controller;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Component;importjavax.websocket.*;importjavax.websocket.server.PathParam;importjavax.websocket.server.ServerEndpoint;importjava.io.IOException;importjava.util.concurrent.ConcurrentHashMap;/** * @Author houdehong * @Date 2024/3/21 14:16 * @Description **/@Component@ServerEndpoint("/api/ws/{sid}")@Slf4jpublicclassWebSocketServer{privateString sid;privatestaticfinalConcurrentHashMap<String,Session>SESSION_MAP=newConcurrentHashMap<>();/** * 连接成功 */@OnOpenpublicvoidonOpen(Session session,@PathParam("sid")String sid){this.sid = sid;SESSION_MAP.put(sid, session); log.info("有新连接:sid:{},sessionId:{},当前连接数:{}", sid, session.getId(),SESSION_MAP.size());}/** * 连接关闭 */@OnClosepublicvoidonClose(Session session){SESSION_MAP.remove(this.sid); log.info("连接关闭,sid:{},session id:{}!当前连接数:{}",this.sid, session.getId(),SESSION_MAP.size());}/** * 收到消息 */@OnMessagepublicvoidonMessage(String message,Session session){ log.info("收到消息:{},内容:{}", sid, message);if("ping".equals(message)){try{ session.getBasicRemote().sendText("pong");}catch(IOException e){ log.error("onMessage 推送消息失败:{},内容:{}", sid, message);}}else{// 排除自己// sendMeasureDataInfoExcludeSelf(message, sid);// 发给所有客户端包括自己sendMeasureDataInfo(message);}}/** * 连接错误 */@OnErrorpublicvoidonError(Session session,Throwable error){ log.error("{} 发生错误", session.getId(), error);}/** * 群发消息 */publicvoidsendMeasureDataInfo(String message){for(String sid :SESSION_MAP.keySet()){Session session =SESSION_MAP.get(sid);try{ session.getBasicRemote().sendText(message);}catch(IOException e){ log.error("推送消息失败:{},内容:{}", sid, message);} log.info("推送消息:{},内容:{}", sid, message);}}/** * 群发消息,排除消息发起者 * @param message * @param sidSelf */privatevoidsendMeasureDataInfoExcludeSelf(String message,String sidSelf){for(String sid :SESSION_MAP.keySet()){if(sidSelf.equals(sid)){continue;}Session session =SESSION_MAP.get(sid);try{ session.getBasicRemote().sendText(message);}catch(IOException e){ log.error("sendMeasureDataInfoExcludeSelf 推送消息失败:{},内容:{}", sid, message);} log.info("sendMeasureDataInfoExcludeSelf 推送消息:{},内容:{}", sid, message);}}}
  4. 测试至此,springboot整合websocket作为服务就搭建完成了,我们可以随便百度打开一个在线的websocket测试工具,请求一下试试,请求地址是ws://ip:port/api/ws/{sid}, 其中sid可以随便指定一个字符串,这里的sid主要是用来区分客户端,实际场景下可以在前端生成全局唯一的标识。图片:在这里插入图片描述控制台打印信息:在这里插入图片描述

2、SpringBoot集成websocket作为客户端

有时,我们需要调用第三方的websocket服务,然后将接收到的数据处理之后,或持久化到数据库,或是需要解析数据重新封装为前端需要的数据结构,这个时候我们就需要作为客户端来进行使用。

实现步骤:

  1. 添加springboot服务作为客户端的依赖<dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.8</version></dependency>
  2. 继承WebSocketClient,重写方法,加入自己的逻辑@Slf4jpublicclassMyWebSocketClientextendsWebSocketClient{publicMyWebSocketClient(URI serverUri){super(serverUri);}@OverridepublicvoidonOpen(ServerHandshake arg0){ log.info("------ WebSocketClient onOpen ------");}@OverridepublicvoidonClose(int arg0,String arg1,boolean arg2){ log.info("------ WebSocket onClose ------{}",arg1);}@OverridepublicvoidonError(Exception arg0){ log.error("------ WebSocket onError ------{}",arg0);}@OverridepublicvoidonMessage(String response){ log.info("-------- 接收到服务端数据: "+ response +"--------");}}
  3. 获取websocketClient实例在这里我写的wsServerUrl即为上面websocket作为服务端的地址@ComponentpublicclassWebSocketClientConfigurer{privatefinalString wsServerUrl ="ws://127.0.0.1:8081/api/ws/123wer";@BeanpublicWebSocketClientwebSocketClient(){try{MyWebSocketClient webSocketClient =newMyWebSocketClient(newURI(wsServerUrl)); webSocketClient.connect();return webSocketClient;}catch(URISyntaxException e){ e.printStackTrace();}returnnull;}}
  4. 为了好演示我加了一个controller来进行调用@RestController@RequestMapping("ws-client")publicclassWebsocketClient{@ResourceprivateMyWebSocketClient webSocketClient;@GetMapping("send/{message}")publicvoidsendRequest(@PathVariableString message){ webSocketClient.send(message);}}

3. 测试

至此,我们已经搭好了一个websocket的服务器和一个websocket的客户端,我们可以同时把这两个服务跑起来,做一个调用。
注意:需要先启动服务端,再启动客户端,客户端会无法创建连接,报空指针异常。
服务端启动:
在这里插入图片描述客户端启动:
在这里插入图片描述现在我们向客户端的controller请求一个消息:
你可以用postman或者其他api工具,我现在图简单直接在浏览器发起:

在这里插入图片描述客户端控制台日志:

在这里插入图片描述服务端控制台日志:
在这里插入图片描述OK,大功告成。
整套源码包地址


本文转载自: https://blog.csdn.net/hou_zi/article/details/136911831
版权归原作者 侯德红 所有, 如有侵权,请联系我们删除。

“SpringBoot集成websocket作为客户端和服务端的代码案例”的评论:

还没有评论