文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Springboot整合Websocket实现后端向前端主动推送消息案例

2024-12-03 07:50

关注

在手机上相信都有来自服务器的推送消息,比如一些及时的新闻信息,这篇文章主要就是实现这个功能,只演示一个基本的案例。使用的是websocket技术。

一、什么是websocke

tWebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通信,学过计算机网络都知道,既然是全双工,就说明了服务器可以主动发送信息给客户端。这与我们的推送技术或者是多人在线聊天的功能不谋而合。

为什么不使用HTTP 协议呢?这是因为HTTP是单工通信,通信只能由客户端发起,客户端请求一下,服务器处理一下,这就太麻烦了。于是websocket应运而生。

下面我们就直接开始使用Springboot开始整合。以下案例都在我自己的电脑上测试成功,你可以根据自己的功能进行修改即可。

二、整合websocket

1、环境配置

Idea 2018专业版(已破解)

Maven 4.0.0

SpringBoot 2.2.2

websocket 2.1.3

jdk 1.8

下面我们新建一个普通的Springboot项目。

2、添加依赖

  1.  
  2.       
  3.          org.springframework.boot 
  4.          spring-boot-starter-web 
  5.       
  6.       
  7.          org.springframework.boot 
  8.          spring-boot-starter-test 
  9.          test 
  10.       
  11.       
  12.          org.springframework.boot 
  13.          spring-boot-starter-websocket 
  14.          2.1.3.RELEASE 
  15.       
  16.   

3、在application.properties文件修改端口号

一句话:server.port=8081

4、新建config包,创建WebSocketConfig类

  1. 1@Configuration 
  2. 2public class WebSocketConfig { 
  3. 3    @Bean 
  4. 4    public ServerEndpointExporter serverEndpointExporter() { 
  5. 5        return new ServerEndpointExporter(); 
  6. 6    } 
  7. 7} 

5、新建service包,创建WebSocketServer类

  1. @ServerEndpoint("/websocket/{sid}"
  2. @Component 
  3. public class WebSocketServer { 
  4.     static Log log= LogFactory.getLog(WebSocketServer.class); 
  5.     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 
  6.     private static int onlineCount = 0; 
  7.     //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 
  8.     private static CopyOnWriteArraySet webSocketSet 
  9.             = new CopyOnWriteArraySet(); 
  10.     //与某个客户端的连接会话,需要通过它来给客户端发送数据 
  11.     private Session session; 
  12.     //接收sid 
  13.     private String sid=""
  14.      
  15.     @OnOpen 
  16.     public void onOpen(Session session,@PathParam("sid") String sid) { 
  17.         this.session = session; 
  18.         webSocketSet.add(this);     //加入set中 
  19.         addOnlineCount();           //在线数加1 
  20.         log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount()); 
  21.         this.sid=sid; 
  22.         try { 
  23.             sendMessage("连接成功"); 
  24.         } catch (IOException e) { 
  25.             log.error("websocket IO异常"); 
  26.         } 
  27.     } 
  28.      
  29.     @OnClose 
  30.     public void onClose() { 
  31.         webSocketSet.remove(this);  //从set中删除 
  32.         subOnlineCount();           //在线数减1 
  33.         log.info("有一连接关闭!当前在线人数为" + getOnlineCount()); 
  34.     } 
  35.      
  36.     @OnMessage 
  37.     public void onMessage(String message, Session session) { 
  38.         log.info("收到来自窗口"+sid+"的信息:"+message); 
  39.         //群发消息 
  40.         for (WebSocketServer item : webSocketSet) { 
  41.             try { 
  42.                 item.sendMessage(message); 
  43.             } catch (IOException e) { 
  44.                 e.printStackTrace(); 
  45.             } 
  46.         } 
  47.     } 
  48.     @OnError 
  49.     public void onError(Session session, Throwable error) { 
  50.         log.error("发生错误"); 
  51.         error.printStackTrace(); 
  52.     } 
  53.     //实现服务器主动推送 
  54.     public void sendMessage(String message) throws IOException { 
  55.         this.session.getBasicRemote().sendText(message); 
  56.     } 
  57.     //群发自定义消息 
  58.     public static void sendInfo(String message,@PathParam("sid") String sid)  
  59.         throws IOException { 
  60.         log.info("推送消息到窗口"+sid+",推送内容:"+message); 
  61.         for (WebSocketServer item : webSocketSet) { 
  62.             try { 
  63.                 //这里可以设定只推送给这个sid的,为null则全部推送 
  64.                 if(sid==null) { 
  65.                     item.sendMessage(message); 
  66.                 }else if(item.sid.equals(sid)){ 
  67.                     item.sendMessage(message); 
  68.                 } 
  69.             } catch (IOException e) { 
  70.                 continue
  71.             } 
  72.         } 
  73.     } 
  74.     public static synchronized int getOnlineCount() { 
  75.         return onlineCount; 
  76.     } 
  77.     public static synchronized void addOnlineCount() { 
  78.         WebSocketServer.onlineCount++; 
  79.     } 
  80.     public static synchronized void subOnlineCount() { 
  81.         WebSocketServer.onlineCount--; 
  82.     } 

6、新建controller包,创建Mycontroller类

  1. @Controller 
  2. public class MyController { 
  3.     //页面请求 
  4.     @GetMapping("/socket/{cid}"
  5.     public ModelAndView socket(@PathVariable String cid) { 
  6.         ModelAndView mav=new ModelAndView("/socket"); 
  7.         mav.addObject("cid", cid); 
  8.         return mav; 
  9.     } 
  10.     //推送数据接口 
  11.     @ResponseBody 
  12.     @RequestMapping("/socket/push/{cid}"
  13.     public String pushToWeb(@PathVariable String cid,String message) { 
  14.         try { 
  15.             WebSocketServer.sendInfo(message,cid); 
  16.         } catch (IOException e) { 
  17.             e.printStackTrace(); 
  18.             return "推送失败"
  19.         } 
  20.         return "发送成功"
  21.     } 
  22. }} 

7、新建一个websocket.html页面

  1.  
  2.  
  3.     name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
  4.     "text/javascript"
  5.         var socket; 
  6.         if (typeof (WebSocket) == "undefined") { 
  7.             console.log("您的浏览器不支持WebSocket"); 
  8.         } else { 
  9.             console.log("您的浏览器支持WebSocket"); 
  10.             //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接   
  11.             socket = new WebSocket("ws://localhost:8081/websocket/1"); 
  12.             //打开事件   
  13.             socket.onopen = function () { 
  14.                 console.log("Socket 已打开"); 
  15.                 socket.send("这是来自客户端的消息" + location.href + new Date()); 
  16.             }; 
  17.             //获得消息事件   
  18.             socket.onmessage = function (msg) { 
  19.                 console.log(msg.data); 
  20.             }; 
  21.             //关闭事件   
  22.             socket.onclose = function () { 
  23.                 console.log("Socket已关闭"); 
  24.             }; 
  25.             //发生了错误事件   
  26.             socket.onerror = function () { 
  27.                 alert("Socket发生了错误"); 
  28.             } 
  29.         } 
  30.      
  31.  
  32.  

 

现在开发服务器和网页就可以看到效果了。一般情况下Springboot2+Netty+Websocket的组合方式更加的常用一下。这个只是给出了一个基本的案例,你可以根据自己的需求进行更改。

本文转载自微信公众号「愚公要移山」,可以通过以下二维码关注。转载本文请联系愚公要移山公众号。

 

来源:愚公要移山内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯