赞
踩
最近使用WebSocket开发了一个与Android设备进行数据传输的项目,由于是第一次使用WebSocket,所以将代码记录下来,方便以后查阅。
SpringBoot使用WebSocket还是比较方便的,直接引入依赖就可以使用。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
需要新建一个WebSocketConfig类,用于启用WebSocket的支持,实现也是很简单,几句代码搞定。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * WebSocket配置 * * @author w * @date 2023/05/20 15:30 */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
主要核心代码都在WebSocketServer里面,里面涉及多个注解,现在简单介绍一下各个注解的作用。
主要是将目前的类定义成一个WebSocket服务端, 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务端。
如果使用@ServerEndpoint(“/”)的话,使用 ws://localhost:端口号/ 就可以进行连接;如果后面加地址参数,比如像@ServerEndpoint(“/test”),呢访问地址就变成 ws://localhost:端口号/test 。
用于在WebSocket连接成功时执行特定的操作。在WebSocket API中,OnOpen是一个回调函数,一般用于在客户端与服务器端建立连接时执行一些初始化操作。
连接关闭时触发。
接收到消息时触发此方法,用于一些数据的处理操作。
当发生错误时触发。
import cn.hutool.log.Log; import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * WebSocket控制器 * * @author w * @date 2023/05/20 15:35 */ @ServerEndpoint("/") @RestController public class WebSocketServer { private static final Log log = Log.get(); /** * concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketController对象。 */ private static ConcurrentHashMap<String, SocketContextExt> webSocketMap = new ConcurrentHashMap<>(); /** * 与某个客户端的连接会话,需要通过它来给客户端发送数据 */ private Session session; /** * 接收id */ private String id; private static WebSocketService webSocketService; @Autowired public void setWebSocketService(WebSocketService webSocketService) { WebSocketServer.webSocketService = webSocketService; } /** * 当建立连接时 * * @author w * @date 2023/05/20 15:35 */ @OnOpen public void onOpen(Session session) { log.info("WebSocket服务=====》新客户端连接... 设备:{}", session.getId()); this.session = session; this.id = session.getId(); log.info("WebSocket服务=====》已建立连接... 地址:{} 设备:{}", session.getRequestURI(), id); } /** * 当关闭连接时 * * @author w * @date 2023/05/20 15:35 */ @OnClose public void onClose(Session session) { if (webSocketMap.containsKey(id)) { webSocketMap.remove(id); log.info("WebSocket服务=====》已关闭并删除连接... 设备:{}", session.getId()); } else { log.info("WebSocket服务=====》已关闭连接... 设备:{}", session.getId()); } } /** * 当接收到消息时 * * @author w * @date 2023/05/20 15:35 */ @OnMessage public void onMessage(Session session, String message) { log.info("WebSocket服务=====》收到客户端:{} 消息:{}", session.getId(), message); // 解析字符串,如果成功;则进行下一步;否则提示错误 try { JSONObject jsonObject = JSONObject.parseObject(message); String method = jsonObject.getString("method"); // 进行数据处理 webSocketService.dealSocketDataPort(session, message, method); } catch (Exception e) { log.error("WebSocket服务=====》解析数据异常:" + e.getMessage()); } } /** * 添加Socket扩展通道 * * @param session * @param deviceCode */ public void addSocketContextExt(Session session, String deviceCode, Long deviceId) { log.info("WebSocket服务=====》新增扩展通道,设备编号:{}", deviceCode); SocketContextExt sce = new SocketContextExt(); sce.setDeviceId(deviceId); sce.setDeviceCode(deviceCode); sce.setConnectTime(new Date()); sce.setLastTime(new Date()); sce.setSession(session); sce.setServer(this); // 如果已经包含该设备id,则移除后重新加入 if (webSocketMap.containsKey(session.getId())) { webSocketMap.remove(session.getId()); webSocketMap.put(session.getId(), sce); } else { // 否则直接加入 webSocketMap.put(session.getId(), sce); } log.info("WebSocket服务=====》添加后设备通道数量:" + webSocketMap.size()); } /** * 获取设备连接通道;如果不存在返回null * * @param id * @return */ public SocketContextExt getContextExt(String id) { SocketContextExt ext = webSocketMap.get(id); return null == ext ? null : ext; } /** * 根据设备编号获取连接通道 * * @param deviceCode * @return */ public SocketContextExt getContextExtByDeviceCode(String deviceCode) { Iterator<Map.Entry<String, SocketContextExt>> ite = webSocketMap.entrySet().iterator(); while (ite.hasNext()) { Map.Entry<String, SocketContextExt> tmp = ite.next(); SocketContextExt sce = tmp.getValue(); if (deviceCode.equals(sce.getDeviceCode())) { return sce; } } return null; } /** * 当发生错误时 * * @author w * @date 2023/05/20 15:30 */ @OnError public void onError(Session session, Throwable e) { log.info("WebSocket服务=====》设备{}出现未知错误... {}", session.getId(), e.getMessage()); e.printStackTrace(); } /** * 消息发送方法 * * @author w * @date 2023/05/20 15:35 */ public void sendMessage(String message, Session session) { try { log.info("WebSocket服务=====》给设备{}发送消息{}", session.getId(), message); session.getBasicRemote().sendText(message); } catch (Exception e) { log.error("WebSocket服务=====》给设备{}发送消息出现错误: {}", session.getId(), e.getMessage()); e.printStackTrace(); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。