在手机上相信都有来自服务器的推送消息,好比一些及时的新闻信息,这篇文章主要就是实现这个功能,只演示一个基本的案例。使用的是websocket技术。
javascript
1、什么是websocket
WebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通讯,学过计算机网络都知道,既然是全双工,就说明了服务器能够主动发送信息给客户端。这与咱们的推送技术或者是多人在线聊天的功能不谋而合。html
为何不使用HTTP 协议呢?这是由于HTTP是单工通讯,通讯只能由客户端发起,客户端请求一下,服务器处理一下,这就太麻烦了。因而websocket应运而生。java
下面咱们就直接开始使用Springboot开始整合。如下案例都在我本身的电脑上测试成功,你能够根据本身的功能进行修改便可。web
2、整合websocket
一、环境配置redis
名称 | 版本 |
---|---|
Idea | 2018专业版(已破解) |
Maven | 4.0.0 |
SpringBoot | 2.2.2 |
websocket | 2.1.3 |
jdk | 1.8 |
下面咱们新建一个普通的Springboot项目。spring
二、添加依赖浏览器
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>
三、在application.properties文件修改端口号安全
一句话:server.port=8081服务器
四、新建config包,建立WebSocketConfig类微信
1@Configuration
2public class WebSocketConfig {
3 @Bean
4 public ServerEndpointExporter serverEndpointExporter() {
5 return new ServerEndpointExporter();
6 }
7}
五、新建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}
六、新建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}
七、新建一个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的组合方式更加的经常使用一下。这个只是给出了一个基本的案例,你能够根据本身的需求进行更改。
推荐阅读:
Springboot整合mybatis(注解并且能看明白版本)
SpringBoot系列(2)整合MongoDB实现增删改查
过年了,病毒很严重,在家好好学习,祝各位过年,吃好喝好,保护好本身和家人
本文分享自微信公众号 - 愚公要移山(fdd_sxu_nwpu)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。