1. pom配置
添加spring-boot-starter-websocket起步依赖,继承spring-boot-starter-parent。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns
xmlns:xsi
xsi:schemaLocation
<groupId>com.tm.sbia</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>sbia-feature-websocket</artifactId>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
</project>
2. 创建WebSocketHandler
接收Socket客户端传递的文本信息,打印日志,等待2s后向客户端发送信息polo!
Socket连接发布和关闭时打印日志。
package com.tm.sbia.feature.websocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
/**
* 消息处理器
*/
public class MarcoHandler extends AbstractWebSocketHandler {
private Logger LOGGER = LoggerFactory.getLogger(MarcoHandler.class);
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
LOGGER.info("Received message: " + message.getPayload());
Thread.sleep(2000);
session.sendMessage(new TextMessage("polo!"));
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
LOGGER.info("Connection established!");
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
LOGGER.info("Connection closed!");
}
}
3. 在Java配置中启用WebSocket并映射消息处理器
通过@EnableWebSocket启用WebSocket,注册路径/marco的处理器为MarcoHandler。
package com.tm.sbia.feature.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
* WebSocket Handler configuration
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(marcoHandler(), "/marco");
}
@Bean
public MarcoHandler marcoHandler() {
return new MarcoHandler();
}
}
4. 客户端实现
客户端建立到WebSocket服务器的连接,发送文本Marco,收到信息后打印信息,然后重新发送Marco,总共发送10次。
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "ws://" + window.location.host + "/marco";
var output;
var count = 0;
function init()
{
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
doSend("Marco!");
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
function onMessage(evt)
{
writeToScreen('<span >RESPONSE: ' + evt.data+'</span>');
if(count++ > 8) {
websocket.close();
} else {
setTimeout(function(){doSend("Marco!")}, 2000);
}
}
function onError(evt)
{
writeToScreen('<span >ERROR:</span> ' + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
5. 客户端访问
浏览器发送upgrade请求,建立Socket连接,执行socket通信。
展示所有的messag信息。