SpringBoot整合WebSocket之如何保存连接session完成实时推送
springboot+websocket
目前项目中需要做一个实时推送的功能,需要使用到websocket,之前写的demo都没效了,涉及到多方业务时,需要实时保存websocket中的session,然后再其他的业务模块中进行调用。
话不多说,先上代码!
@Component
@ServerEndpoint(value = "/websocket")
@EnableWebSocket
public class ZyWebSocket {
//用来存放每个客户端对应的WebSocket对象
private static CopyOnWriteArraySet<ZyWebSocket> webSockets = new CopyOnWriteArraySet<>();
//与客户端的连接会话,需要通过此会话来给客户端发送数据
private Session session;
//连接成功调用的方法
@OnOpen
public void onOpen(Session session){
this.session = session;
webSockets.add(this);
System.out.println("有新的连接加入" +session.getId()+session.getProtocolVersion()+"---"+session.getContainer());
try {
//返回发送信息
session.getBasicRemote().sendText("连接成功");
} catch (Exception e) {
e.printStackTrace();
}
}
//内部方法,发送消息的方法。发送文本消息
public void sendMessage(Session session,String msg){
try {
System.out.println(msg);
if(session==null){
System.out.println("session为空");
}else{
session.getBasicRemote().sendText(msg);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
//外部方法
public void sendMessage(String msg){
sendMessage(session,msg);
}
很奇特的是,内部能够触发,但是外部接口进行调用时,使用@Autowired获取这个Websocket服务时,调用它的发送方法,拿不到对应的session。每次都会报一个空指针的异常,也就是session为空。
后来发现,原来是因为我在外部接口调用时,产生了另一个客户端(因为我使用的是postman),并且websocket默认是多例的。因此每次去拿session时,拿到的都不是原本连接上的session。所以这里需要将这个session保存下来进行使用。
接着上代码。。
private static List<Session> sessionList = new ArrayList<>();
public static List<Session> getSessionList() {
return sessionList;
}
外部调用的时候,直接调用get方法拿到SessionList()拿到其中的session进行推送工作。
session.getBasicRemote().sendText(msg);
这样,就完成了一次外部调用websocket进行动态信息的实时推送任务了。
最后上一段前端js
let info = document.getElementById("info");
function con() {
if("WebSocket" in window){
alert("您的浏览器支持WebSocket,正在为您提供实时推送服务")
var socket = new WebSocket("ws://127.0.0.1:9911/websocket");
socket.onopen=()=>{
alert("已经连接上了")
}
socket.onmessage=(message)=>{
var msg = message.data;
var info1 = info.innerHTML;
console.log(info1);
info1 += msg+"</br>";
info.innerHTML=info1;
}
socket.onclose=()=>{
alert("连接关闭")
}
}else{
alert("您的浏览器不支持WebSocket无法为您提供实时推送服务")
}
}