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

在手机上相信都有来自服务器的推送消息,比如一些及时的新闻信息,这篇文章主要就是实现这个功能,只演示一
首页 新闻资讯 行业资讯 Springboot整合Websocket实现后端向前端主动推送消息案例

[[389702]]

在手机上相信都有来自服务器的推送消息,比如一些及时的新闻信息,这篇文章主要就是实现这个功能,只演示一个基本的案例。使用的是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、添加依赖

复制

<dependencies>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-web</artifactId>      </dependency>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-test</artifactId>          <scope>test</scope>      </dependency>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-websocket</artifactId>          <version>2.1.3.RELEASE</version>      </dependency>  </dependencies>
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

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

一句话:server.port=8081

4、新建config包,创建WebSocketConfig类

复制

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

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

5、新建service包,创建WebSocketServer类

复制

@ServerEndpoint("/websocket/{sid}") @Component public class WebSocketServer {     static Log log= LogFactory.getLog(WebSocketServer.class);     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。     private static int onlineCount = 0;     //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。     private static CopyOnWriteArraySet<WebSocketServer> webSocketSet             = new CopyOnWriteArraySet<WebSocketServer>();     //与某个客户端的连接会话,需要通过它来给客户端发送数据     private Session session;     //接收sid     private String sid="";     /**      * 连接建立成功调用的方法      */     @OnOpen     public void onOpen(Session session,@PathParam("sid") String sid) {         this.session = session;         webSocketSet.add(this);     //加入set中         addOnlineCount();           //在线数加1         log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());         this.sid=sid;         try {             sendMessage("连接成功");         } catch (IOException e) {             log.error("websocket IO异常");         }     }     /**      * 连接关闭调用的方法      */     @OnClose     public void onClose() {         webSocketSet.remove(this);  //从set中删除         subOnlineCount();           //在线数减1         log.info("有一连接关闭!当前在线人数为" + getOnlineCount());     }     /**      * 收到客户端消息后调用的方法      * @param message 客户端发送过来的消息      */     @OnMessage     public void onMessage(String message, Session session) {         log.info("收到来自窗口"+sid+"的信息:"+message);         //群发消息         for (WebSocketServer item : webSocketSet) {             try {                 item.sendMessage(message);             } catch (IOException e) {                 e.printStackTrace();             }         }     }     @OnError     public void onError(Session session, Throwable error) {         log.error("发生错误");         error.printStackTrace();     }     //实现服务器主动推送     public void sendMessage(String message) throws IOException {         this.session.getBasicRemote().sendText(message);     }     //群发自定义消息     public static void sendInfo(String message,@PathParam("sid") String sid)          throws IOException {         log.info("推送消息到窗口"+sid+",推送内容:"+message);         for (WebSocketServer item : webSocketSet) {             try {                 //这里可以设定只推送给这个sid的,为null则全部推送                 if(sid==null) {                     item.sendMessage(message);                 }else if(item.sid.equals(sid)){                     item.sendMessage(message);                 }             } catch (IOException e) {                 continue;             }         }     }     public static synchronized int getOnlineCount() {         return onlineCount;     }     public static synchronized void addOnlineCount() {         WebSocketServer.onlineCount++;     }     public static synchronized void subOnlineCount() {         WebSocketServer.onlineCount--;     }
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

  • 23.

  • 24.

  • 25.

  • 26.

  • 27.

  • 28.

  • 29.

  • 30.

  • 31.

  • 32.

  • 33.

  • 34.

  • 35.

  • 36.

  • 37.

  • 38.

  • 39.

  • 40.

  • 41.

  • 42.

  • 43.

  • 44.

  • 45.

  • 46.

  • 47.

  • 48.

  • 49.

  • 50.

  • 51.

  • 52.

  • 53.

  • 54.

  • 55.

  • 56.

  • 57.

  • 58.

  • 59.

  • 60.

  • 61.

  • 62.

  • 63.

  • 64.

  • 65.

  • 66.

  • 67.

  • 68.

  • 69.

  • 70.

  • 71.

  • 72.

  • 73.

  • 74.

  • 75.

  • 76.

  • 77.

  • 78.

  • 79.

  • 80.

  • 81.

  • 82.

  • 83.

  • 84.

  • 85.

  • 86.

  • 87.

  • 88.

  • 89.

6、新建controller包,创建Mycontroller类

复制

@Controller public class MyController {     //页面请求     @GetMapping("/socket/{cid}")     public ModelAndView socket(@PathVariable String cid) {         ModelAndView mav=new ModelAndView("/socket");         mav.addObject("cid", cid);         return mav;     }     //推送数据接口     @ResponseBody     @RequestMapping("/socket/push/{cid}")     public String pushToWeb(@PathVariable String cid,String message) {         try {             WebSocketServer.sendInfo(message,cid);         } catch (IOException e) {             e.printStackTrace();             return "推送失败";         }         return "发送成功";     } }}
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

7、新建一个websocket.html页面

复制

<html> <head>     <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />     <script type="text/javascript">         var socket;         if (typeof (WebSocket) == "undefined") {             console.log("您的浏览器不支持WebSocket");         } else {             console.log("您的浏览器支持WebSocket");             //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接               socket = new WebSocket("ws://localhost:8081/websocket/1");             //打开事件               socket.onopen = function () {                 console.log("Socket 已打开");                 socket.send("这是来自客户端的消息" + location.href + new Date());             };             //获得消息事件               socket.onmessage = function (msg) {                 console.log(msg.data);             };             //关闭事件               socket.onclose = function () {                 console.log("Socket已关闭");             };             //发生了错误事件               socket.onerror = function () {                 alert("Socket发生了错误");             }         }     </script> </head> </html>
  • 1.

  • 2.

  • 3.

  • 4.

  • 5.

  • 6.

  • 7.

  • 8.

  • 9.

  • 10.

  • 11.

  • 12.

  • 13.

  • 14.

  • 15.

  • 16.

  • 17.

  • 18.

  • 19.

  • 20.

  • 21.

  • 22.

  • 23.

  • 24.

  • 25.

  • 26.

  • 27.

  • 28.

  • 29.

  • 30.

  • 31.

  • 32.

 

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

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