maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
1.首先创建websocket的配置类
package com.ddm.business.WebSocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @PACKAGE_NAME: com.ddm.business.WebSocket
* @CLASS_NAME: WebSocketConfig
* @author: Yuqiang Lian
* @DATE: 2023/8/2 11:52 周三
**/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2.创建websocket核心服务
package com.ddm.business.WebSocket;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @PACKAGE_NAME: com.ddm.business.WebSocket
* @CLASS_NAME: WebSocketService
* @author: Yuqiang Lian
* @DATE: 2023/8/2 11:52 周三
**/
@Slf4j
@Service
@ServerEndpoint(value = "/myService/{userId}")
public class WebSocketService {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static AtomicInteger onlineCount = new AtomicInteger(0);;
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
private static ConcurrentHashMap<String,WebSocketService> webSocketMap = new ConcurrentHashMap<>();
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的session对象。
*/
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
private String userId = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
this.session = session;
this.userId = userId;
if(webSocketMap.containsKey(userId) && sessionMap.containsKey(userId)){
webSocketMap.remove(userId);
sessionMap.remove(userId);
sessionMap.put(userId,session);
webSocketMap.put(userId,this);
}else{
webSocketMap.put(userId,this);
sessionMap.put(userId,session);
addOnlineCount();
}
log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
subOnlineCount();
}
log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*/
@OnMessage
public void onMessage(String message, Session session) {
this.session = session;
log.info("收到客户端消息 -> {}",message);
JSONObject obj_message= (JSONObject) JSON.parse(message);
log.info("收到客户端消息=========", obj_message);
//服务端收到客户端的消息并推送给客户端
// sendMessage(message);
sendOneMessage("112",message);
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session, Throwable error) {
log.error(error.getMessage());
}
/**
* 实现服务器主动推送 可以通过controller调用此方法实现主动推送
*/
public void sendMessage(String message){
try {
Set<Map.Entry<String, Session>> entries = sessionMap.entrySet();
for (Map.Entry<String, Session> next : entries) {
Session session = next.getValue();
session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
/**
* 此为单点消息
*/
public void sendOneMessage(String userId, String message) {
Session session = sessionMap.get(userId);
if (session != null && session.isOpen()) {
try {
log.info("【websocket消息】 单点消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 此为单点消息(多人)
*/
public void sendMoreMessage(String[] userIds, String message) {
for (String userId : userIds) {
Session session = sessionMap.get(userId);
if (session != null && session.isOpen()) {
try {
log.info("【websocket消息】 单点消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount.get();
}
public static synchronized void addOnlineCount() {
WebSocketService.onlineCount.getAndIncrement();
}
public static synchronized void subOnlineCount() {
WebSocketService.onlineCount.getAndDecrement();
}
}
3.html 通讯
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>websocket通讯</title>
</head>
<body>
<p>userId:<input id="userId" name="userId" type="text" value="10"></p>
<p>msg:<input id="contentText" name="contentText" type="text" value="hello websocket"></p>
<p>操作:<button onclick="openSocket()">开启socket</button></p>
<p>操作:<button onclick="sendMessage()">发送消息</button></p>
</body>
<script type="application/javascript">
let socket;
function openSocket() {
if(socket != null){
socket.close();
socket = null;
}
let userId = document.getElementById('userId').value
socket = new WebSocket("ws://localhost:9000/myService/"+userId);
//打开事件
socket.onopen = function() {
console.log("websocket已打开");
};
//获得消息事件
socket.onmessage = function(msg) {
console.log(msg.data);
};
//关闭事件
socket.onclose = function() {
console.log("websocket已关闭");
};
//发生了错误事件
socket.onerror = function() {
console.log("websocket发生了错误");
}
}
function sendMessage() {
let contentText = document.getElementById('contentText').value
socket.send(contentText);
}
</script>
</html>
4.微信小程序
data: {
globalData: {
socketTask: null,
socketOpen: false,
},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.connectToWebSocket()
},
// 连接到WebSocket服务器
connectToWebSocket() {
let globalData = this.data.globalData
let userId = 112
var socketTask = wx.connectSocket({
url: 'ws://127.0.0.1:8895/myService/' + userId, // WebSocket服务器地址 80
//url: 'wss://127.0.0.1:8895/myService/' + userId, // WebSocket服务器地址 443
});
globalData.socketTask = socketTask
this.setData({
globalData: globalData
})
// console.log("处理接收到的消息",globalData)
socketTask.onOpen(() => {
console.log('WebSocket连接已打开');
globalData.socketOpen = true;
});
socketTask.onMessage(res => {
console.log('收到消息:', res.data);
// 处理接收到的消息
});
socketTask.onError(error => {
console.log('WebSocket连接启动失败', error);
});
socketTask.onClose(() => {
console.log('WebSocket连接已关闭');
globalData.socketOpen = false;
});
},
// 发送消息
sendMessage(message) {
let globalData = this.data.globalData
if (globalData.socketOpen) {
globalData.socketTask.send({
data: message,
});
}
},