websocket服务器主动推送之一对多、多对多
关键类的编写
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置文件
server:
port: 9090
SessionPool
public class SessionPool {
/**
* 使用ConcurrentHashMap是为了保证线程的安全,它比HashTable效率要高
*/
public static Map<String, Session> sessions = new ConcurrentHashMap<>();
/**
* 关闭session
* @param sessionId 客户名
*/
public static void close(String sessionId) {
for (String userId : sessions.keySet()) {
Session session = sessions.get(userId);
if (session.getId().equals(sessionId)) {
sessions.remove(userId);
break;
}
}
}
/**
* 指定发送
* @param sessionId 接收端sessionId
* @param message 消息
*/
public static void sendMessage(String sessionId, String message) {
sessions.get(sessionId).getAsyncRemote().sendText(message);
}
/**
* 群发
* @param message 消息
*/
public static void sendMessage(String message) {
for (String s : sessions.keySet()) {
sessions.get(s).getAsyncRemote().sendText(message);
}
}
}
WebSocketConfig
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
WebSocketEndpoint
@ServerEndpoint(value = "/websocket/{userId}")
@Component
public class WebSocketEndpoint {
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session=null;
/**
* 连接建立成功调用的方法
*
* @param session 客户端的session
* @param userId 客户端的名称
*/
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
// 把会话存入到连接池中
this.session = session;
SessionPool.sessions.put(userId, session);
}
/**
* 接受客户端发送的消息
*
* @param message 发送的消息
* @param session 发送消息的客户端
*/
@OnMessage
public void onMessage(String message, Session session) {
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 关闭连接
*
* @param session 要关闭的客户端
*/
@OnClose
public void onClose(Session session) throws IOException {
SessionPool.close(session.getId());
session.close();
}
}
SendMessageController
@RestController
public class SendMessageController {
/**
* 群发
* @param msg 消息
* @return String
*/
@RequestMapping("send")
public String sendMessageWebsocekt(String msg) {
SessionPool.sendMessage(msg);
return "群发消息推送成功……";
}
/**
* 指定消息推送
*
* @param data zhangsan:张三你好!我是服务器的推送消息,lisi:李四你好!我是服务器的推送消息
* @return String
*/
@RequestMapping("sendToUser")
public String sendToUserMessageWebsocekt(String data) {
System.out.println(data);
String[] split = data.split(",");
Map<String, String> msg = new HashMap<>();
for (String s : split) {
String[] split1 = s.split(":");
msg.put(split1[0], split1[1]);
}
for (String s : msg.keySet()) {
SessionPool.sendMessage(s, msg.get(s));
}
return "指定消息推送成功……";
}
}
群发测试
先与服务器连接
ws://localhost:9090/websocket/zhangsan
ws://localhost:9090/websocket/lisi
然后调用发送消息端口
localhost:9090/send?msg=我是群发消息
针对不同的用户发送不同的消息
先于服务器连接
ws://localhost:9090/websocket/zhangsan
ws://localhost:9090/websocket/lisi
给张三、李四发送消息
localhost:9090/sendToUser?data=zhangsan:张三你好!我是服务器的推送消息,lisi:李四你好!我是服务器的推送消息
张三
李四