一、首先构建服务端(java)的websocket
1、首先在pom文件中引入websocket的maven依赖
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、新建一个WebSocket的配置类,用来开启WebSocket的支持
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
//注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3、新建WebSocketService,用来创建和处理连接
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
//注意:@ServerEndpoint注解中的访问地址一定要支持无token访问
@ServerEndpoint(value = "/anon/websocket/{userName}")
@Component
public class WebSocketService {
private static final Logger log = LoggerFactory.getLogger(WebSocketService.class);
//静态变量,用来记录当前在线连接数
private static int onlineCount = 0;
//用来存放每个客户端对应的WebSocketServer对象
private static ConcurrentHashMap<String, Session> webSocketMap = new ConcurrentHashMap<>();
/**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
private Session session;
/**接收userName*/
private String userName="";
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(Session session, @PathParam("userName") String userName) {
if(!webSocketMap.containsKey(userName)){
addOnlineCount(); // 在线数 +1
}
this.session = session;
this.userName= userName;
webSocketMap.put(userName, session);
log.info("用户连接:"+userName+",当前在线人数为:" + getOnlineCount());
try {
sendMessage("来自后台的反馈:连接成功");
} catch (IOException e) {
log.error("用户:"+userName+",网络异常!!!!!!");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if(webSocketMap.containsKey(userName)){
if(webSocketMap.size()>0){
//从set中删除
subOnlineCount();
}
webSocketMap.remove(userName);
}
log.info(userName+"用户退出,当前在线人数为:" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到用户消息:"+userName+",报文:"+message);
sendMessage(userName,message);
}
/**
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误:"+this.userName+",原因:"+error.getMessage());
error.printStackTrace();
}
/**
* 连接服务器成功后主动推送
*/
public void sendMessage(String message) throws IOException {
synchronized (session){
this.session.getBasicRemote().sendText(message);
}
}
/**
* 向指定客户端发送消息
* @param userName
* @param message
*/
public static void sendMessage(String userName,String message){
try {
Session session = webSocketMap.get(userName);
if(session!=null){
session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketService.onlineCount = WebSocketService.onlineCount + 1;
}
public static synchronized void subOnlineCount() {
WebSocketService.onlineCount = WebSocketService.onlineCount - 1;
}
}
二、构建客户端(js)的websocket
1、创建一个index.js文件,把下方封装websocket方法的代码保存
let websock = null;//建立的连接
let timeoutObj = null;//心跳定时器
let timeout = 5000;//心跳间隔(秒)
let websocket = {
//建立websocket链接
initWebSocket (val) {
//val为用户的唯一标识
const wsUrl = "ws://127.0.0.1:8090/mars/anon/websocket/"+val;
//建立连接
websock = new WebSocket(wsUrl);
//连接成功
websock.onopen = this.websocketonopen;
//连接错误
websock.onerror = this.websocketonerror;
//接收信息
websock.onmessage = this.websocketonmessage;
//连接关闭
websock.onclose = this.websocketclose;
},
//连接成功事
websocketonopen () {
//开启心跳
startTimeout()
console.log('WebSocket连接已建立');
},
//连接失败事件
websocketonerror () {
console.log('WebSocket连接失败');
},
//连接关闭事件
websocketclose () {
console.log('WebSocket连接关闭');
},
//接收服务器推送的信息
websocketonmessage (event) {
console.log(event.data,"这里是服务端给客户端推送的数据")
},
}
//开启心跳定时器
let startTimeout = function (){
timeoutObj = setInterval(() => {
if (websock.readyState === 1) {
websock.send("这是给服务端发送的数据");
console.log("心跳开启")
}
}, timeout);
};
//关闭心跳定时器
let stopTimeout = function (){
clearInterval(timeoutObj);
};
export default websocket;
2、在需要使用websocket的地方使用import引入index.js,然后调用initWebSocket方法即可完成
import websocket from "/index.js";
websocket.initWebSocket("用户唯一标识")