spring-boot-websocket总结回顾
前言
websocket
的内容比我预期的要少,本来打算分三次分享,但是经过昨天和前天的分享,核心内容已经完结了,所以我们今天来做一个简单小结。
websocket总结回顾
相比于我们前两天刚分享的security
,websocket
确实比较少,不过它内容虽然不多,但是这项技术却很有用,比如你要搭建一个个人聊天系统或者做一个客服组件,那websocket
就是最佳选择,而且兼容性方便也是没得说,根据我的实际测试IE11
本身是支持websocket
,如果老一点的IE
,我们也可以通过STOMP
来兼容。
今天我们的核心内容也是从一张脑图开始,公众号后台回复【sping-websocket】获取脑图源文件:
核心依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
核心配置
创建一个服务节点池,本质上它就是一个节点容器
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
节点服务
@ServerEndpoint
需要指定节点地址,客户端根据节点地址与服务端通信
@ServerEndpoint("/ws")
@Service
public class WebSocketService {
...
}
监听方法
@OnOpen
:客户端建立连接时会调用该方法@OnOpen
public void onOpen(Session session) {
String name = nameMap.get(session.getUserPrincipal().getName());
this.session = session;
webSocketServiceSet.add(this);
addOnlineCount();
logger.info("有新连接加入!当前在线人数为: {}", onlineCount.get());
webSocketServiceSet.parallelStream().forEach(item -> {
try {
sendMessage(item.getSession(), String.format("%s加入群聊!", name));
} catch (Exception e) {
logger.error("发送消息异常:", e);
}
});
}Session
参数
@OnMessage
:客户端发送消息时调用该方法@OnMessage
public void onMessage(String message, Session session) {
logger.info("来自客户端的消息:{}", message);
webSocketServiceSet.parallelStream().forEach(item -> {
String name = nameMap.get(session.getUserPrincipal().getName());
logger.info("{}发送了一条消息:{}", name, message);
try {
item.sendMessage(item.getSession(), String.format("%s:%s", name, message));
} catch (IOException e) {
e.printStackTrace();
}
});
}message
Session
参数
@OnClose
:客户端关闭websocket
连接时回调该方法@OnClose
public void onClose(Session session) {
logger.info("{}退出群聊!", session.getUserPrincipal().getName());
webSocketServiceSet.remove(this);
subOnlineCount();
}Session
参数
@OnError
:客户端发生错误时调用该方法@OnError
public void onError(Session session, Throwable t) {
logger.error("发生错误:", t);
}Session
Throwable
参数
前端
创建websocket对象
var websocket = new WebSocket("ws://localhost:8989/ws")
指定回调函数
open
websocket.onopen = function () {
// 方法实现
}error
websocket.onerror = function () {
// 方法实现
}message
websocket.message = function () {
// 方法实现
}close
websocket.onclose = function () {
// 方法实现
}
发送消息
websocket.send(message)
STOMP兼容
对于不支持websocket
的浏览器,我们需要通过stomp
协议进行兼容,但是目前我接触到的浏览器包括IE
都是支持websocket
的。
配置类
注解
@EnableWebSocketMessageBroker
作用:启用
websocketMessageBroker
配置方法
指定客户端订阅路径前缀
registry.enableSimpleBroker("/sub", "/queue")
指定服务端点请求前缀
registry.setApplicationDestinationPrefixes("/request")
注册节点
registry.addEndpoint("/socket").withSockJS()
registerStompEndpoints()
configureMessageBroker()
:
接口
发送广播消息
@MessageMapping("/send")
@SendTo("/sub/chat")
public String sendMessage(String value) {
logger.info("发送消息内容:{}", value);
return value;
}发送私有消息
@MessageMapping("/sendToUser")
public void sendToUser(Principal principal, String body) {
String srcUser = principal.getName();
String[] args = body.split(": ");
String desUser = args[0];
String message = String.format("【%s】给你发来消息:%s", webSocketService.getNameMap().get(srcUser), args[1]);
// 发送到用户和监听地址
simpMessagingTemplate.convertAndSendToUser(desUser, "/queue/customer", message);
}
前端
引入js包
stomp.js
sockjs.js
建立
STOMP
连接创建
SockJS
实例var socket = new SockJS('/socket');
创建
stompClient
var stompClient = Stomp.over(socket);
建立连接
stompClient.connect({}, function (frame) {
// 建立连接后的回调
setConnected(true);
})断开
stomp
连接stompClient.disconnect()
发送消息
stompClient.send("/request/send", {}, message)
接收方订阅消息
stompClient.connect({}, function () {
console.log("notice socket connected !");
// 订阅消息地址
stompClient.subscribe('/sub/chat', function (data) {
$('#receive').html(data.body);
});
});
总结
websocket
的内容相对比较简单,而且配置也不复杂,所以今天也没有太多要补充说明的,各位小伙伴如果对于之前的知识点还有疑问,可以再回顾下: