SpringBoot使用WebSocket实现向前端推送消息功能

 更新时间:2024年05月27日 09:32:53   作者:rise_  
WebSocket协议是基于TCP的一种新的网络协议,它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端,本文给大家介绍了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推送消息的资料请关注脚本之家其它相关文章!

相关文章

  • Java线程中的Timer和TimerTask原理详解

    Java线程中的Timer和TimerTask原理详解

    这篇文章主要介绍了Java线程中的Timer和TimerTask原理详解,Timer和TimerTask成对出现,Timer是定时器,TimerTask是定时任务,换句话说,定时任务TimerTask是给定时器Timer执行的具体任务,需要的朋友可以参考下
    2023-10-10
  • Java编程中利用InetAddress类确定特殊IP地址的方法

    Java编程中利用InetAddress类确定特殊IP地址的方法

    这篇文章主要介绍了Java编程中利用InetAddress类确定特殊IP地址的方法,InetAddress类是Java网络编程中一个相当实用的类,需要的朋友可以参考下
    2015-11-11
  • Java实现简单的贪吃蛇游戏

    Java实现简单的贪吃蛇游戏

    这篇文章主要介绍了Java实现简单的贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Idea如何配置Maven才能优先从本地仓库获取依赖(亲测方法有效)

    Idea如何配置Maven才能优先从本地仓库获取依赖(亲测方法有效)

    对于Idea怎么配置Maven才能优先从本地仓库获取依赖,网上说法有很多种,都不太靠谱,最终都没有效果,最好的解决方法是通过修改maven配置文件settings.xml,本文给大家介绍的非常详细,需要的朋友参考下吧
    2023-10-10
  • java中volatile关键字的作用详解

    java中volatile关键字的作用详解

    这篇文章主要介绍了java中volatile关键字的作用详解,volatile可以保证,若一个线程改变了某块内存的值,其他线程是可见的,以至于其他线程能及时更新这块内存,需要的朋友可以参考下
    2023-09-09
  • Gson中@JsonAdater注解的几种方式总结

    Gson中@JsonAdater注解的几种方式总结

    这篇文章主要介绍了Gson中@JsonAdater注解的几种方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 详解Sentinel流量控制限流框架的原理与使用

    详解Sentinel流量控制限流框架的原理与使用

    Sentinel 是一个高可用、高扩展、高稳定性的开源流量控制和熔断降级框架,可以在分布式系统中实现实时的流量控制,下面就来和大家聊聊是具体如何操作的吧
    2023-05-05
  • SpringBoot中集成screw(螺丝钉)实现数据库表结构文档生成方法

    SpringBoot中集成screw(螺丝钉)实现数据库表结构文档生成方法

    这篇文章主要介绍了SpringBoot中集成screw(螺丝钉)实现数据库表结构文档生成,下面以连接mysql数据库并生成html格式的数据库结构文档为例,插件的使用方式除可以使用代码外,还可以使用Maven插件的方式,需要的朋友可以参考下
    2024-07-07
  • java实现带有背景图片的窗体

    java实现带有背景图片的窗体

    这篇文章主要为大家详细介绍了java实现带有背景图片的窗体,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • JAVA SpringBoot jar程序 Systemctl生产环境部署方案

    JAVA SpringBoot jar程序 Systemctl生产环境部署方案

    这篇文章主要介绍了JAVA SpringBoot jar程序 Systemctl生产环境部署方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03

最新评论