SpringBoot使用WebSocket实现向前端推送消息功能
WebSocket简介
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
SpringBoot整合WebSocket的相关依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
WebSokcet工具类记录当前的在线连接对链接进行操作
public class WebsocketUtil { /** * 记录当前在线的Session */ private static final Map<String, Session> ONLINE_SESSION = new ConcurrentHashMap<>(); /** * 添加session * @param userId * @param session */ public static void addSession(String userId, Session session){ // 此处只允许一个用户的session链接。一个用户的多个连接,我们视为无效。 ONLINE_SESSION.putIfAbsent ( userId, session ); } /** * 关闭session * @param userId */ public static void removeSession(String userId){ ONLINE_SESSION.remove ( userId ); } /** * 给单个用户推送消息 * @param session * @param message */ public static void sendMessage(Session session, String message){ if(session == null){ return; } // 同步 RemoteEndpoint.Async async = session.getAsyncRemote (); async.sendText ( message ); } /** * 向所有在线人发送消息 * @param message */ public static void sendMessageForAll(String message) { //jdk8 新方法 ONLINE_SESSION.forEach((sessionId, session) -> sendMessage(session, message)); } }
WebSocket接口处理类
/** * websocket接口处理类 */ @Component @ServerEndpoint(value = "/chat/{userId}") public class WebsocketController { /** * 连接事件,加入注解 * @param userId * @param session */ @OnOpen public void onOpen(@PathParam(value = "userId") String userId, Session session) { String message = "[" + userId + "]加入聊天室!!"; // 添加到session的映射关系中 WebsocketUtil.addSession(userId, session); // 广播通知,某用户上线了 // WebsocketUtil.sendMessageForAll(message); } /** * 连接事件,加入注解 * 用户断开链接 * * @param userId * @param session */ @OnClose public void onClose(@PathParam(value = "userId") String userId, Session session) { String message = "[" + userId + "]退出了聊天室..."; // 删除映射关系 WebsocketUtil.removeSession(userId); // 广播通知,用户下线了 WebsocketUtil.sendMessageForAll(message); } /** * 当接收到用户上传的消息 * * @param userId * @param session */ @OnMessage public void onMessage(@PathParam(value = "userId") String userId, Session session, String message) { String msg = "[" + userId + "]:" + message; System.out.println("接收到信息:" + msg); // 直接广播 WebsocketUtil.sendMessageForAll(msg); } /** * 处理用户活连接异常 * * @param session * @param throwable */ @OnError public void onError(Session session, Throwable throwable) { try { session.close(); } catch (IOException e) { e.printStackTrace(); } throwable.printStackTrace(); } }
服务器端单个用户推送消息
@PostMapping("/send") public void send(@RequestParam("id") String id,@RequestParam("message")String message) { Session session = ONLINE_SESSION.get(id); WebsocketUtil.sendMessage(session,message); System.out.println("发送成功"); }
使用Apifox进行测试
添加连接服务端的WebSocket接口
连接成功:
服务端推送消息
客户端收到的消息
WebSocket工具类里面有群发的方法,大家想用可以直接调用,这里就不进行演示了
问题一:如何在上面WebSocket接口处理类中注入其他的Bean?
我也是在一次工作中遇到这样的问题,今天正好和大家讲一下如何解决
查阅资料才知道WebSocket接口处理类使用@ServerEndPoint注解表明他是一个WebSocket端点,因此Spring不会将其纳入Spring容器的管理范围,WebSocket的生命周期和Spring Bean 的生命周期并不一致,所以通过@Autowired 注解注入得到的都是空的Bean 无法使用
我们自定义一个工具类手动获取Bean在 WebSocket接口处理类中使用:
/** *AppUtils类 * * @author qiancj * @since 2020-06-30 13:02 */ @Component("appUtils") public class AppUtils { /** * 应用上下文 */ private static ApplicationContext context; @Resource public void setApplicationContext(ApplicationContext c) { context = c; } /** * 获取配置参数 * * @param property 配置参数名 * @return 配置参数值 */ public static String getProperty(String property) { return context.getEnvironment().getProperty(property); } /** * 获取bean对象 * * @param requiredType Class * @param <T> T * @return bean对象 */ public static <T> T getBean(Class<T> requiredType) { return context.getBean(requiredType); } /** * 获取bean对象 * * @param name bean name * @param requiredType Class * @param <T> T * @return bean对象 */ public static <T> T getBean(String name, Class<T> requiredType) { return context.getBean(requiredType); } }
使用:
MessageService messageService = AppUtils.getBean(MessageService.class);
然后我们就可以使用messageService调用Service层相关的方法了。
问题解决。
以上就是SpringBoot使用WebSocket实现向前端推送消息功能的详细内容,更多关于SpringBoot WebSocket推送消息的资料请关注脚本之家其它相关文章!
相关文章
SpringCloud-Alibaba-Sentinel服务降级,热点限流,服务熔断
这篇文章主要介绍了SpringCloud-Alibaba-Sentinel服务降级,热点限流,服务熔断,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-12-12
最新评论