<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-websocketartifactId>
<version>2.2.7.RELEASEversion>
dependency>
package com.example.poi.utils;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import java.io.IOException;
/**
* @Author xu
* @create 2023/9/11 18
*/
@ClientEndpoint
@Component
public class MyWebSocketClient {
public Session session;
@OnOpen
public void onOpen(Session session) {
this.session = session;
System.out.println("WebSocket2连接已打开");
}
@OnMessage
public void onMessage(String message) {
System.out.println("收到消息2:" + message);
}
@OnClose
public void onClose() {
System.out.println("客户端关闭2");
}
@OnError
public void onError(Throwable throwable) {
System.err.println("发生错误2:" + throwable.getMessage());
}
public void sendMessage(String message) throws IOException {
session.getBasicRemote().sendText(message);
}
}
package com.example.poi.utils;
import cn.hutool.json.JSONObject;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ObjectUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @Author xu
* @create 2023/7/21 19
*/
@ServerEndpoint("/websocket/{sid}")
@Component
@Slf4j
public class WebSocketServer {
static Log log = LogFactory.get(WebSocketServer.class);
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
public Session session;
//接收sid
private String sid = "";
/**
* 连接建立成功调用的方法
*
* @param session
* @param sid
*/
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在线数加1
log.info("有新窗口开始监听:" + sid + ",当前在线人数为" + getOnlineCount());
this.sid = sid;
/*try {
sendMessage("连接成功");
} catch (IOException e) {
log.error("websocket IO异常");
}*/
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
* 客户端发送过来的消息
*
* @param message
* @param session
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到来自窗口" + sid + "的信息:" + message);
//群发消息
for (WebSocketServer item : webSocketSet) {
if (ObjectUtils.equals(item.sid, sid)) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", sid);
item.sendMessage(jsonObject.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 实现服务器主动推送
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 获取存在的webSocket
*/
public CopyOnWriteArraySet<WebSocketServer> getWebSocketServer() {
return webSocketSet;
}
public String getSid(){
return sid;
}
public void close2(String ss){
for (WebSocketServer webSocketServer : webSocketSet) {
if (webSocketServer.sid.equals(ss)) {
webSocketSet.remove(webSocketServer);
log.info("删除了:"+ss);
}
}
subOnlineCount(); //在线数减1
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 发送消息
*
* @param message
* @param sid
* @throws IOException
*/
public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException {
log.info("推送消息到窗口" + sid + ",推送内容:" + message);
for (WebSocketServer item : webSocketSet) {
try {
//这里可以设定只推送给这个sid的,为null则全部推送
if (sid == null) {
item.sendMessage(message);
} else if (item.sid.equals(sid)) {
item.sendMessage(message);
}
} catch (IOException e) {
continue;
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
/**
* 必须要有这个bean才能生效使用webSocketServer
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
/**static修饰,保证每一个WebSocketServer只有一个UserMapper实例*/
private static UserMapper userMapper;
@Autowired
public void setUserMapper(UserMapper userMapper) {
this.userMapper=userMapper;
}
@SneakyThrows
@GetMapping("/testSql")
public List<EntityDemo> testSql(String id) {
/** WebSocket服务器的地址*/
try {
Random random = new Random();
Integer i = random.nextInt(5) + 1;
CopyOnWriteArraySet<WebSocketServer> webSocketServerSet = webSocketServer.getWebSocketServer();
for (WebSocketServer socketServer : webSocketServerSet) {
if (socketServer.getSid().equals(i.toString())) {
webSocketServer.close2(i.toString());
return null;
}
}
URI uri = new URI("ws://127.0.0.1:9088/test/websocket/" + i);
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(myWebSocketClient, uri);
myWebSocketClient.sendMessage("你好" + i);
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info("++++++");
return null;
}
@ServerEndpoint("/websocket/{sid}")
@Component
@Slf4j
public class WebSocketServer {
private static EntityDemoServiceImpl entityDemoService;
public static void setEntityDemoService(EntityDemoServiceImpl entityDemoService) {
WebSocketServer.entityDemoService = entityDemoService;
}
@Service
public class EntityDemoServiceImpl extends ServiceImpl<EntityDemoMapper, EntityDemo> implements IEntityDemoService {
@PostConstruct
public void init() {
WebSocketServer.setEntityDemoService(this);
}
}