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

一、什么是websocket

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

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

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

二、整合websocket

1、环境配置

名称版本
Idea2018专业版(已破解)
Maven4.0.0
SpringBoot2.2.2
websocket2.1.3
jdk1.8

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

2、添加依赖

 1    <dependencies>
2        <dependency>
3            <groupId>org.springframework.boot</groupId>
4            <artifactId>spring-boot-starter-web</artifactId>
5        </dependency>
6        <dependency>
7            <groupId>org.springframework.boot</groupId>
8            <artifactId>spring-boot-starter-test</artifactId>
9            <scope>test</scope>
10        </dependency>
11        <dependency>
12            <groupId>org.springframework.boot</groupId>
13            <artifactId>spring-boot-starter-websocket</artifactId>
14            <version>2.1.3.RELEASE</version>
15        </dependency>
16    </dependencies>

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}

5、新建service包,创建WebSocketServer类

 1@ServerEndpoint("/websocket/{sid}")
2@Component
3public 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<WebSocketServer> webSocketSet
9            = new CopyOnWriteArraySet<WebSocketServer>();
10    //与某个客户端的连接会话,需要通过它来给客户端发送数据
11    private Session session;
12    //接收sid
13    private String sid="";
14    /**
15     * 连接建立成功调用的方法
16     */

17    @OnOpen
18    public void onOpen(Session session,@PathParam("sid") String sid) {
19        this.session = session;
20        webSocketSet.add(this);     //加入set中
21        addOnlineCount();           //在线数加1
22        log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
23        this.sid=sid;
24        try {
25            sendMessage("连接成功");
26        } catch (IOException e) {
27            log.error("websocket IO异常");
28        }
29    }
30    /**
31     * 连接关闭调用的方法
32     */

33    @OnClose
34    public void onClose() {
35        webSocketSet.remove(this);  //从set中删除
36        subOnlineCount();           //在线数减1
37        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
38    }
39    /**
40     * 收到客户端消息后调用的方法
41     * @param message 客户端发送过来的消息
42     */

43    @OnMessage
44    public void onMessage(String message, Session session) {
45        log.info("收到来自窗口"+sid+"的信息:"+message);
46        //群发消息
47        for (WebSocketServer item : webSocketSet) {
48            try {
49                item.sendMessage(message);
50            } catch (IOException e) {
51                e.printStackTrace();
52            }
53        }
54    }
55    @OnError
56    public void onError(Session session, Throwable error) {
57        log.error("发生错误");
58        error.printStackTrace();
59    }
60    //实现服务器主动推送
61    public void sendMessage(String message) throws IOException {
62        this.session.getBasicRemote().sendText(message);
63    }
64    //群发自定义消息
65    public static void sendInfo(String message,@PathParam("sid") String sid) 
66        throws IOException 
{
67        log.info("推送消息到窗口"+sid+",推送内容:"+message);
68        for (WebSocketServer item : webSocketSet) {
69            try {
70                //这里可以设定只推送给这个sid的,为null则全部推送
71                if(sid==null) {
72                    item.sendMessage(message);
73                }else if(item.sid.equals(sid)){
74                    item.sendMessage(message);
75                }
76            } catch (IOException e) {
77                continue;
78            }
79        }
80    }
81    public static synchronized int getOnlineCount() {
82        return onlineCount;
83    }
84    public static synchronized void addOnlineCount() {
85        WebSocketServer.onlineCount++;
86    }
87    public static synchronized void subOnlineCount() {
88        WebSocketServer.onlineCount--;
89    }
90}

6、新建controller包,创建Mycontroller类

 1@Controller
2public 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<html>
2<head>
3    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
4    <script type="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    
</script>
31</head>
32</html>

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


更多相关文章

  1. 微信公众号自动回复图文消息
  2. 客户端请求服务器时的状态码讲解
  3. 推荐一款神仙颜值的 ZooKeeper 客户端工具
  4. Node.js如何将Ajax成功消息传递给app.js
  5. 使用Selectize和Ajax时,在Bootstrap模式中显示Rails错误消息
  6. 当AJAX响应来自PHP文件时,如何显示以消息为中心的加载器图像&防止
  7. 关于 客户端发现响应内容类型为“text/html; charset=utf-8”,但
  8. Jquery - 表单验证,为错误消息添加css样式
  9. HTML5 windows和iframe之间传递消息

随机推荐

  1. Ruby和Python哪个更强大?学习分析
  2. Java面试题全集(12)
  3. 面试官:什么是CSRF?(你的钱为什么被转走,这篇
  4. 2020年5A PMP 经验分享
  5. 静态链表
  6. 栈和队列就是这么简单
  7. 解读容器的 2020:寻找云原生的下一站
  8. JVM中一个小知识点:深堆和浅堆的认识
  9. Linux网络基础概念
  10. 十道简单算法题