框架搭建
新建一个Spring Boot项目,artifactId为spring-boot-websocket-socketjs,项目结构如下图所示:
项目的pom内容如下:
12345678910111213141516171819202122232425262728293031323334353637383940 | <?xml version=”1.0” encoding=”UTF-8”?> |
---|---|
引入了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
的四个方法:
- afterConnectionEstablished,和客户端链接成功的时候触发该方法;
- handleTransportError,和客户端连接失败的时候触发该方法;
- afterConnectionClosed,和客户端断开连接的时候触发该方法;
- handleTextMessage,和客户端建立连接后,处理客户端发送的请求。
WebSocketSession
对象代表每个客户端会话,包含许多实用方法:
方法见名知意,就不赘述了。
此外,因为我们的目的是实现和客户端的通信,并且内容为文本内容,所以我们继承的是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
。
上面代码的含义是,当客户端通过/connect
url和服务端连接通信时,使用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
,断开和服务端的连接。
通信测试
启动项目,浏览器访问:http://localhost:8080/client.html: