框架搭建

新建一个Spring Boot项目,artifactId为spring-boot-websocket-socketjs,项目结构如下图所示:
8. springboot2使用websocket - 图1
项目的pom内容如下:

12345678910111213141516171819202122232425262728293031323334353637383940 <?xml version=”1.0” encoding=”UTF-8”?> 4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.5.RELEASE cc.mrbird spring-boot-websocket-socketjs 0.0.1-SNAPSHOT spring-boot-websocket-socketjs Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-websocket org.springframework.boot spring-boot-maven-plugin

引入了spring-boot-starter-websocket和spring-boot-starter-web依赖。

构建服务端

在cc.mrbird.socket目录下新建handler包,然后在该包下新建MyStringWebSocketHandler继承TextWebSocketHandler

12345678910111213141516171819202122232425262728293031323334353637383940414243 @Componentpublic class MyStringWebSocketHandler extends TextWebSocketHandler { private Logger log = LoggerFactory.getLogger(this.getClass()); @Override public void afterConnectionEstablished(WebSocketSession session) { log.info(“和客户端建立连接”); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { session.close(CloseStatus.SERVER_ERROR); log.error(“连接异常”, exception); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { super.afterConnectionClosed(session, status); log.info(“和客户端断开连接”); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 获取到客户端发送过来的消息 String receiveMessage = message.getPayload(); log.info(receiveMessage); // 发送消息给客户端 session.sendMessage(new TextMessage(fakeAi(receiveMessage))); // 关闭连接 // session.close(CloseStatus.NORMAL); } private static String fakeAi(String input) { if (input == null || “”.equals(input)) { return “你说什么?没听清︎”; } return input.replace(‘你’, ‘我’) .replace(“吗”, “”) .replace(‘?’, ‘!’) .replace(‘?’, ‘!’); }}

该类重写了父类AbstractWebSocketHandler的四个方法:
8. springboot2使用websocket - 图2

  • afterConnectionEstablished,和客户端链接成功的时候触发该方法;
  • handleTransportError,和客户端连接失败的时候触发该方法;
  • afterConnectionClosed,和客户端断开连接的时候触发该方法;
  • handleTextMessage,和客户端建立连接后,处理客户端发送的请求。

WebSocketSession对象代表每个客户端会话,包含许多实用方法:
8. springboot2使用websocket - 图3
方法见名知意,就不赘述了。
此外,因为我们的目的是实现和客户端的通信,并且内容为文本内容,所以我们继承的是TextWebSocketHandler;如果传输的是二进制内容,则可以继承BinaryWebSocketHandler,更多信息可以自行查看WebSocketHandler的子类。
接着在cc.mrbird.socket目录下新建configure包,然后在该包下新建WebSocketServerConfigure配置类:

123456789101112 @Configuration@EnableWebSocketpublic class WebSocketServerConfigure implements WebSocketConfigurer { @Autowired private MyStringWebSocketHandler myStringWebSocketHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myStringWebSocketHandler, “/connect”).withSockJS(); }}

@EnableWebSocket用于开启WebSocket相关功能,我们注入了上面创建的MyStringWebSocketHandler,并将其注册到了WebSocketHandlerRegistry
上面代码的含义是,当客户端通过/connecturl和服务端连接通信时,使用MyStringWebSocketHandler处理会话。withSockJS的含义是,通信的客户端是通过SockJS实现的,下面会介绍到。

构建客户端

SockJS是一个JS插件,用于构建WebSocket,兼容性好。
在resources目录下新建static包,然后在该包下新建client.html:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 <!DOCTYPE html>

聊天记录:

html,css那些都不重要,重要的是我们引入了SockJS库。在connect()方法中,我们通过new SockJS(/connect)和上面的服务端建立了Socket通信。SockJS对象包含几个常用的实用方法:

  • onopen,和服务端讲了连接后的回调方法;
  • onmessage,服务端返回消息时的回调方法;
  • onclose,和服务端断开连接的回调方法;
  • send,发送消息给服务端;
  • close,断开和服务端的连接。

上面的JS较为简单,其他逻辑自己看看吧。

通信测试

启动项目,浏览器访问:http://localhost:8080/client.html
8. springboot2使用websocket - 图4