@Slf4j
@Component
@ServerEndpoint("/ws/{userId}")
public class WebSocketServer {
@Autowired
private IChatService chatService;
public static Map<Long, Session> sessionMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("userId") Long userId) {
log.info("用户: {} 与服务器建立连接", userId);
sessionMap.put(userId, session);
}
@OnMessage
public void onMessage(String message, Session senderSession, @PathParam("userId") Long senderUserId) {
ChatMessage receivedMessage = JSON.parseObject(message, ChatMessage.class);
sendAndPersistMessage(receivedMessage);
}
@OnClose
public void onClose(Session session, @PathParam("userId") Long userId) {
log.info("用户: {} 与服务器断开连接", userId);
sessionMap.remove(userId);
}
private void sendAndPersistMessage(ChatMessage message) {
log.info("用户: {} 向用户: {} 发送了如下消息: {}", message.getSenderId(), message.getReceiverId(), message.getContent());
if (chatService != null) {
Chat chat = Chat.builder()
.userId1(message.getSenderId())
.userId2(message.getReceiverId())
.content(message.getContent())
.createTime(LocalDateTime.now())
.build();
chatService.save(chat);
} else {
log.info("消息持久化失败...");
}
String jsonMessage = JSON.toJSONString(message);
Session receiverSession = sessionMap.get(message.getReceiverId());
if (receiverSession != null) {
try {
receiverSession.getBasicRemote().sendText(jsonMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
22:47:05 INFO 14040 --- [io-8080-exec-10] com.lichun.websocket.WebSocketServer : 用户: 1 与服务器建立连接
22:47:09 INFO 14040 --- [nio-8080-exec-1] com.lichun.websocket.WebSocketServer : 用户: 2 与服务器建立连接
22:47:14 INFO 14040 --- [nio-8080-exec-2] com.lichun.websocket.WebSocketServer : 用户: 1 向用户: 2 发送了如下消息: 你好
22:47:14 INFO 14040 --- [nio-8080-exec-2] com.lichun.websocket.WebSocketServer : 消息持久化失败...
(1)修改AccompanyApplication.java
ConfigurableApplicationContext applicationContext = SpringApplication.run(AccompanyApplication.class, args);
WebSocketServer.setApplicationContext(applicationContext);
@EnableTransactionManagement
@SpringBootApplication
public class AccompanyApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(AccompanyApplication.class, args);
WebSocketServer.setApplicationContext(applicationContext);
}
}
(2)修改WebSocketServer.java
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext applicationContext) {
WebSocketServer.applicationContext = applicationContext;
}
IChatService chatService = (IChatService) applicationContext.getBean("chatServiceImpl");
Chat chat = Chat.builder()
.userId1(message.getSenderId())
.userId2(message.getReceiverId())
.content(message.getContent())
.createTime(LocalDateTime.now())
.build();
chatService.save(chat);
@Slf4j
@Component
@ServerEndpoint("/ws/{userId}")
public class WebSocketServer {
public static Map<Long, Session> sessionMap = new ConcurrentHashMap<>();
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext applicationContext) {
WebSocketServer.applicationContext = applicationContext;
}
@OnOpen
public void onOpen(Session session, @PathParam("userId") Long userId) {
log.info("用户: {} 与服务器建立连接", userId);
sessionMap.put(userId, session);
}
@OnMessage
public void onMessage(String message, Session senderSession, @PathParam("userId") Long senderUserId) {
ChatMessage receivedMessage = JSON.parseObject(message, ChatMessage.class);
sendAndPersistMessage(receivedMessage);
}
@OnClose
public void onClose(Session session, @PathParam("userId") Long userId) {
log.info("用户: {} 与服务器断开连接", userId);
sessionMap.remove(userId);
}
private void sendAndPersistMessage(ChatMessage message) {
log.info("用户: {} 向用户: {} 发送了如下消息: {}", message.getSenderId(), message.getReceiverId(), message.getContent());
IChatService chatService = (IChatService) applicationContext.getBean("chatServiceImpl");
Chat chat = Chat.builder()
.userId1(message.getSenderId())
.userId2(message.getReceiverId())
.content(message.getContent())
.createTime(LocalDateTime.now())
.build();
chatService.save(chat);
String jsonMessage = JSON.toJSONString(message);
Session receiverSession = sessionMap.get(message.getReceiverId());
if (receiverSession != null) {
try {
receiverSession.getBasicRemote().sendText(jsonMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void noticeTimingTimeOut(Long userId1, Long userId2) {
for (Long id : sessionMap.keySet()) {
if (id.equals(userId1) || id.equals(userId2)) {
Session session = sessionMap.get(id);
if (session != null) {
try {
session.getBasicRemote().sendText("时间到...");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
23:00:43 INFO 12252 --- [nio-8080-exec-8] com.lichun.websocket.WebSocketServer : 用户: 1 与服务器建立连接
23:00:47 INFO 12252 --- [nio-8080-exec-5] com.lichun.websocket.WebSocketServer : 用户: 2 与服务器建立连接
23:00:56 INFO 12252 --- [nio-8080-exec-4] com.lichun.websocket.WebSocketServer : 用户: 1 向用户: 2 发送了如下消息: 你好啊
23:00:56 ERROR 12252 --- [nio-8080-exec-4] c.a.druid.pool.DruidAbstractDataSource : discard long time none received connection. , jdbcUrl : jdbc:mysql://127.0.0.1:13306/accompany?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true, jdbcUrl : jdbc:mysql://127.0.0.1:13306/accompany?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true, lastPacketReceivedIdleMillis : 296332
23:00:56 DEBUG 12252 --- [nio-8080-exec-4] com.lichun.mapper.ChatMapper.insert : ==> Preparing: INSERT INTO chat ( user_id1, user_id2, content, create_time ) VALUES ( ?, ?, ?, ? )
23:00:56 DEBUG 12252 --- [nio-8080-exec-4] com.lichun.mapper.ChatMapper.insert : ==> Parameters: 1(Long), 2(Long), 你好啊(String), 2024-01-03T23:00:56.867703800(LocalDateTime)
23:00:56 DEBUG 12252 --- [nio-8080-exec-4] com.lichun.mapper.ChatMapper.insert : <== Updates: 1