SpringBoot中WebSokcet无法注入Bean对象的解决方案

文章描述了一个使用SpringBoot和WebSocket构建的聊天应用中,如何处理WebSocket连接、消息发送、以及在并发环境下遇到的数据库连接超时问题。通过修改ApplicationContext和引入依赖,解决了数据持久化的问题。
摘要由CSDN通过智能技术生成

一、业务场景

@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
  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枯木何日可逢春

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值