- 在pom文件中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
- java后台
@Component
@ServerEndpoint(value = "/webSocketToUser/{id}", configurator = WebSocketConfig.class)
public class WebSocketToUser {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
private static ConcurrentHashMap<String, WebSocketToUser> webSocketSet = new ConcurrentHashMap<>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private static Session session;
//指定的sid,具有唯一性
private static String sid = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(@PathParam("id") String id, Session session, EndpointConfig config) {
//获取WebsocketConfig.java中配置的“sessionId”信息值
String httpSessionId = (String) config.getUserProperties().get("sessionId");
this.session = session;
this.sid = id;
webSocketSet.put(sid, this); //加入set中
addOnlineCount(); //在线数加1
System.out.println("用戶" + sid + "加入!当前在线人数为" + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
System.err.println("来自客户端的消息:" + message);
}
/**
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public boolean sendToUser(String message, String sendUserId) throws IOException {
if (webSocketSet.get(sendUserId) != null) {
if (!sid.equals(sendUserId)) {
return false;
//webSocketSet.get(sendUserId).sendMessage("用户" + sendUserId + "发来消息:" + message);
} else {
webSocketSet.get(sendUserId).sendMessage(message);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
} else {
//如果用户不在线则返回不在线信息给自己
return false;
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketToUser.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketToUser.onlineCount--;
}
}
- 配置类
@Component
public class WebSocketConfig extends ServerEndpointConfig.Configurator{
@Override
/**
* 修改握手信息
*/
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
StandardSessionFacade ssf = (StandardSessionFacade) request.getHttpSession();
if (ssf != null) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
//关键操作
sec.getUserProperties().put("sessionId", httpSession.getId());
//log.info("获取到的SessionID:" + httpSession.getId());
}
super.modifyHandshake(sec, request, response);
}
@Bean
public ServerEndpointExporter serverEndpointConfigurator(){
return new ServerEndpointExporter();
}
}
- 安全框架拦截器放行webScoket
- 前端部分
mounted () {
// 初始化
this.init()
},
init: function () {
if (typeof (WebSocket) === "undefined") {
alert("您的浏览器不支持socket")
} else {
// 实例化socket
//userId是你要发送的用户id
this.socket = new WebSocket("ws://localhost:8080/webSocketToUser/" + userId)
// 监听socket连接
this.socket.onopen = this.open
// 监听socket错误信息
this.socket.onerror = this.error
// 监听socket消息
this.socket.onmessage = this.getMessage
}
},
open: function () {
console.log("socket连接成功")
},
error: function () {
console.log("连接错误")
},
getMessage: function (msg) {
this.openMsg(msg.data)
},
send: function () {
this.socket.send(params)
},
close: function () {
console.log("socket已经关闭")
},
openMsg (msg) {
let _self = this;
this.$notify({
title: '提示',
message: msg,
duration: 0,
type: 'warning',
onClose: function () {
}))
}
});
}
6.注入webSocket, 调用方法
@Autowired
private WebSocketToUser webSocketToUser;
webSocketToUser.sendToUser(自定义消息, 发送用户id);