1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.后端
2.1 配置类(config)
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2.2 WebSocketServer类
@ServerEndpoint("/socket/{wid}")
@Component
public class WebSocketServer {
private static ConcurrentHashMap<Integer,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
//存储哈希表,使用Integer找到对应的WebSocketServer
private Session session;//与当前用户的连接会话
private Integer wid;//当前用户的wid
@OnOpen
public void onOpen(Session session,@PathParam("wid") Integer wid) {
//接收由@ServerEndpoint传入的{wid}
this.session = session;
this.wid = wid;
webSocketMap.put(wid, this);//写入hash表
}
@OnClose
public void onClose() {
webSocketMap.remove(wid);//连接中断时将对应websocket移出
}
public void AppointSending(Integer wid,String message){
//向wid发送message
try {
if(webSocketMap.get(wid) == null){//此用户当前未登录则取消发送
return;
}
webSocketMap.get(wid).session.getBasicRemote().sendText(message);
}catch (Exception e){
e.printStackTrace();
}
}
}
解释:设置@ServerEndpoint(“/socket/{wid}”),其作用类似于controller中常用的@RequestMapping注解,当前端访问此地址时将访问函数@OnOpen
3.前端
let socket;
$(document).ready(function(){
let socketUrl="http://localhost:8080/socket/"+$.cookie("wid");
connetcSocket(socketUrl);
})
function connetcSocket(socketUrl){
socketUrl=socketUrl.replace("https","ws").replace("http","ws");
if(socket != null){
socket.close();
socket = null;
}
socket = new WebSocket(socketUrl);//创建连接
//打开事件
socket.onopen = function() {
console.log("websocket已打开");
};
//获得消息事件
socket.onmessage = function(data) {
//接收消息
let content = data.data;
layer.confirm(content,{icon: 0, title:'任务提醒'},function(index)
{
layer.close(index);
})
};
//关闭事件
socket.onclose = function() {
console.log("websocket已关闭");
};
//发生了错误事件
socket.onerror = function() {
console.log("websocket发生了错误");
}
}
4.后端发送
//用于反向推送
@Autowired
WebSocketServer webSocketServer;//自动注入
private void noticeTask(Integer wid,Integer tid){
//提醒wid要开始tid任务
Task task = taskService.selectTaskByTid(tid);
String content = "项目号:"+task.getPid()+",子任务号:"+task.getTid()+",已经可以开始执行,请留意!";
webSocketServer.AppointSending(wid,content);
}
5.利用websocket实现伪单点登录
用户在每个前端页面均与后端保持websocket连接,其中连接使用账号充当key,当有相同账号的用户登录时查看哈希表中是否存在相同key值,若有则表示重复登录,则后端向前端发送信息,通知其退出登录,在其退出登录后第二个用户再建立连接。
Comment