websocket的概念:
https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
websocket的操作:
一般现在使用websocket的工程都为springboot,所以此篇教程在springboot基础上集成。spring框架本身就实现了一个websocket子项目,只需要引入pom文件
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
然后需要编写一个配置类,开启websocket的支持
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
然后需要封装一个WebSocket类,供其他方法调用此类的发送信息的方法。
@ServerEndpoint(value = "/project/socket/{userId}")
@Component
public class WebSocket {
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocket.class);
private static final ConcurrentHashMap<String, Session> userSessionMap = new ConcurrentHashMap<>();
private String userId = "0";
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
userSessionMap.put(userId, session);
if (userId.equals("undefined")) {
this.userId = "0";
} else {
this.userId = userId;
}
}
@OnMessage
public void onMessage(String message) {
LOGGER.info(String.format("接收到的消息为 %s", message));
sendMessage(message, Integer.valueOf(userId));
}
@OnClose
public void onClose() {
userSessionMap.remove(userId);
LOGGER.info("disConnect userId is {}", userId);
}
@OnError
public void onError(Throwable error) {
LOGGER.error(error.getMessage(), error);
}
/**
* 封装发送信息的方法,当需要发送信息时,其他类的方法可调用此静态方法
* @param message
* @param userId
*/
public static void sendMessage(String message, int userId) {
String userIdStr = String.valueOf(userId);
Session session = userSessionMap.get(userIdStr);
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
LOGGER.error("===========SocketServer send message error", e);
}
// userSessionMap.forEach((k, v) -> {
// if (k.equals(userIdStr)) {
// synchronized (v) {
// try {
// v.getBasicRemote().sendText(message);
// } catch (Exception e) {
// LOGGER.error("===========SocketServer send message error", e);
// }
// }
// }
// });
}
}
使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。