在手機上相信都有來自服務器的推送消息,好比一些及時的新聞信息,這篇文章主要就是實現這個功能,只演示一個基本的案例。使用的是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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。