SpringBoot webSocket给指定登录用户发送消息
首先后端创建一个WebSocketConfig 配置类@Configurationpublic class WebSocketConfig {/*** 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndp
·
首先后端创建一个WebSocketConfig 配置类
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
之后创建一个websoket 连接收发类
这里当前端访问/test/oneToMany/{userId} 建立连接,其中{userId} 为前端传过来当前用户的Id 值。
- 首先第一步、前端访问连接地址为ws://localhost:8080/test/oneToMany/123456
- 之后会进入onOpen 方法**(注意加@OnOpen注解**)连接建立成功调用的方法。获取到用户id 为123456,和生成连接会话Session 对象
- 将Session 根据id 放入clients中保存
- onMessage( 注意加@OnMessage)方法为服务器端收到客户端消息后回调方法;
- 当需要发送发送消息时可根据用户id 拿到对应的Session 对象调用session.getAsyncRemote().sendText(“你要发送的消息”);进行发送。
- 当用户关闭浏览器,或断开连接后。会回调onClose方法(注意加 @OnClose注解)将之前保存的Session会话对象移除。
/**
*
* 前后端交互的类实现消息的接收推送(自己发送给所有人(不包括自己))
*
* @ServerEndpoint(value = "/test/oneToMany") 前端 和后端交互,建立连接
*/
@Slf4j
@ServerEndpoint(value = "/test/oneToMany/{userId}")
@Component
public class OneToManyWebSocket {
/** 记录当前在线连接数 */
private static AtomicInteger onlineCount = new AtomicInteger(0);
/** 存放所有在线的客户端 key 为用户Id */
private static Map<String, Session> clients = new ConcurrentHashMap<>();
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
if(clients.containsKey(userId)){
clients.remove(userId);
clients.put(userId, session);
}else{
onlineCount.incrementAndGet(); // 在线数加1
clients.put(userId, session);
sendMessage("你好啊客户端"+userId,session);
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
for (String userId : clients.keySet()) {
if(clients.get(userId).equals(session)){
clients.remove(session);
onlineCount.decrementAndGet(); // 在线数减1
}
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message
* 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
//this.sendMessage(message, session);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 群发消息
*
* @param message
* 消息内容
*/
public void sendMessage(String message, Session fromSession) {
for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
Session toSession = sessionEntry.getValue();
// 排除掉自己
//if (!fromSession.getId().equals(toSession.getId())) {
log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
toSession.getAsyncRemote().sendText(message);
//}
}
}
/**
* 群发消息
*
* @param message
* 消息内容
*/
public void sendMessage(String message, List<String> ids) {
for (String id : ids) {
Session session = clients.get(id);
if(session!=null){
log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
try {
session.getAsyncRemote().sendText(message);
}catch (Exception e){
log.info("数据发送失败!疑似断开连接", session.getId(), message);
clients.remove(id);
}
}
}
}
public Session getUserSession(String userId){
return clients.get(userId);
}
}
前端测试连接
var websocket = null;
//判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
if ('WebSocket' in window) {
var socketPath = layui.setter.socketPath; // ws://localhost:8080/test/oneToMany/
var userId = $("#user").attr("value"); // 0
websocket = new WebSocket(socketPath+userId); //ws://localhost:8080/test/oneToMany/0
window.websocket = websocket;
} else {
layer.msg("抱歉!您的浏览器不支持websocket可能影响部分功能体验,请升级您的浏览器");
}
//连接发生错误的回调方法
websocket.onerror = function() {
layer.msg("error");
};
//连接成功建立的回调方法
websocket.onopen = function(event) {
//setMessageInnerHTML("open");
send("你好啊服务器");
}
//接收到消息的回调方法
websocket.onmessage = function(event) {
layer.msg(event.data);
}
//连接关闭的回调方法
websocket.onclose = function() {
layer.msg("close");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
websocket.close();
}
//关闭连接
function closeWebSocket() {
websocket.close();
}
//发送消息
function send(message) {
// var message = document.getElementById('text').value;
websocket.send(message);
}
完成测试
更多推荐
已为社区贡献1条内容
所有评论(0)