一、前言
本节简单介绍下如何在spring boot引入websocket,实现简单的客户端与服务端建立长连接并互发送文本消息。
二、框架搭建
2.1 依赖引入
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-websocket</artifactid>
</dependency>2.2 构建服务端
新建handler包,然后在该包下新建mystringwebsockethandler继承textwebsockethandler:
@component
@slf4j
public class mystringwebsockethandler extends textwebsockethandler {
@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,和客户端建立连接后,处理客户端发送的请求。
此外,因为我们的目的是实现和客户端的通信,并且内容为文本内容,所以我们继承的是textwebsockethandler;
如果传输的是二进制内容,则可以继承binarywebsockethandler,更多信息可以自行查看websockethandler的子类。
2.3 配置类
接着新建config包,然后在该包下新建websocketserverconfigure配置类:
@configuration
@enablewebsocket
public class websocketserverconfigure implements websocketconfigurer {
@autowired
private mystringwebsockethandler mystringwebsockethandler;
@override
public void registerwebsockethandlers(websockethandlerregistry websockethandlerregistry) {
websockethandlerregistry.addhandler(mystringwebsockethandler, "/connect").withsockjs();
}
}
@enablewebsocket用于开启websocket相关功能,我们注入了上面创建的mystringwebsockethandler,并将其注册到了websockethandlerregistry。
上面代码的含义是,当客户端通过/connecturl和服务端连接通信时,使用mystringwebsockethandler处理会话。
withsockjs的含义是,通信的客户端是通过sockjs实现的,下面会介绍到。
三、构建客户端
sockjs是一个js插件,用于构建websocket,兼容性好。
在resources目录下新建static包,然后在该包下新建client.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>websocket客户端</title>
<script src="https://cdn.bootcss.com/sockjs-client/0.3.4/sockjs.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
</head>
<body>
<style>
.jumbotron {
width: 100%;
}
#text {
height: 3rem;
font-size: 1rem;
line-height: 3rem;
margin: 1rem;
}
.btn {
margin-right: 5px;
}
#connect {
margin-left: 1rem;
}
#log {
margin: 1rem 0 0 1rem;
}
</style>
<div class="container">
<div class="row">
<div class="jumbotron">
<input type="text" placeholder="请输入你想传输的内容" id="text" class="col-lg-12"/>
<input type="button" value="连接" class="btn btn-info" id="connect" onclick="connect()"/>
<input type="button" value="发送" class="btn btn-success" id="sent" disabled="disabled" onclick="sent()"/>
<input type="button" value="断开" class="btn btn-danger" id="disconnect" disabled="disabled" onclick="disconnect()"/>
<div id="log">
<p>聊天记录:</p>
</div>
</div>
</div>
</div>
<script type="text/javascript">
let text = document.queryselector('#text');
let connectbtn = document.queryselector("#connect");
let sentbtn = document.queryselector("#sent");
let disconnectbtn = document.queryselector("#disconnect");
let logdiv = document.queryselector("#log");
let ws = null;
function connect() {
let targeturi = "/connect";
ws = new sockjs(targeturi);
ws.onopen = function () {
setconnected(true);
log('和服务端连接成功!');
};
ws.onmessage = function (event) {
log('服务端说:' + event.data);
};
ws.onclose = function () {
setconnected(false);
log('和服务端断开连接!')
}
}
function sent() {
if (ws != null) {
ws.send(text.value);
log('客户端说:' + text.value);
} else {
log('请先建立连接!')
}
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
setconnected(false);
}
function log(value) {
let content = document.createelement('p');
content.innerhtml = value;
logdiv.appendchild(content);
text.value = '';
}
function setconnected(connected) {
connectbtn.disabled = connected;
disconnectbtn.disabled = !connected;
sentbtn.disabled = !connected;
}
</script>
</body>
</html>html,css那些都不重要,重要的是我们引入了sockjs库。
在connect()方法中,我们通过new sockjs(/connect)和上面的服务端建立了socket通信。sockjs对象包含几个常用的实用方法:
- onopen,和服务端讲了连接后的回调方法;
- onmessage,服务端返回消息时的回调方法;
- onclose,和服务端断开连接的回调方法;
- send,发送消息给服务端;
- close,断开和服务端的连接。
上面的js较为简单,其他逻辑自己看看吧。
四、通信测试
启动项目,浏览器访问:http://localhost:8080/client.html:

五、总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论