WebSocket項目筆記 html
(如下內容來源於百度百科)前端
握手協議:html5
由於項目要求,個人小程序須要與後端服務器進行長鏈接,以傳送數據。因此我須要在我配置好的Springboot框架中添加WebSocket。十分慶幸的是,Springboot已經集成好了WebSocket了。因此過程並不複雜。看了不少博客,內容都大同小異。java
我有點懵,由於我發現你們都在說的是,客戶端與服務器創建鏈接的過程的實現。因此有幾個問題:程序員
大概就有這些。下面咱們在配置過程當中將問題逐個擊破!web
<!-- 引入 websocket 依賴類--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
package com.cuc.happyseat.config.websocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * 開啓WebSocket支持 */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
這裏對照下面的代碼看:spring
1 package com.cuc.happyseat.websocket; 2 3 import java.io.IOException; 4 import java.util.concurrent.CopyOnWriteArraySet; 5 6 import javax.websocket.EncodeException; 7 import javax.websocket.OnClose; 8 import javax.websocket.OnError; 9 import javax.websocket.OnMessage; 10 import javax.websocket.OnOpen; 11 import javax.websocket.Session; 12 import javax.websocket.server.PathParam; 13 import javax.websocket.server.ServerEndpoint; 14 15 import org.springframework.stereotype.Component; 16 17 /*@ServerEndpoint註解是一個類層次的註解,它的功能主要是將目前的類定義成一個websocket服務器端, 18 * 註解的值將被用於監聽用戶鏈接的終端訪問URL地址,客戶端能夠經過這個URL來鏈接到WebSocket服務器端 19 */ 20 @ServerEndpoint("/websocket/{userID}") 21 @Component 22 public class WebSocketServer { 23 24 //每一個客戶端都會有相應的session,服務端能夠發送相關消息 25 private Session session; 26 27 //接收userID 28 private Integer userID; 29 30 //J.U.C包下線程安全的類,主要用來存放每一個客戶端對應的webSocket鏈接 31 private static CopyOnWriteArraySet<WebSocketServer> copyOnWriteArraySet = new CopyOnWriteArraySet<WebSocketServer>(); 32 33 public Integer getUserID() { 34 return userID; 35 } 36 37 /** 38 * @Name:onOpen 39 * @Description:打開鏈接。進入頁面後會自動發請求到此進行鏈接 40 * @Author:mYunYu 41 * @Create Date:14:46 2018/11/15 42 * @Parameters:@PathParam("userID") Integer userID 43 * @Return: 44 */ 45 @OnOpen 46 public void onOpen(Session session, @PathParam("userID") Integer userID) { 47 this.session = session; 48 this.userID = userID; 49 System.out.println(this.session.getId()); 50 //System.out.println("userID:" + userID); 51 copyOnWriteArraySet.add(this); 52 System.out.println("websocket有新的鏈接, 總數:"+ copyOnWriteArraySet.size()); 53 54 } 55 56 /** 57 * @Name:onClose 58 * @Description:用戶關閉頁面,即關閉鏈接 59 * @Author:mYunYu 60 * @Create Date:14:46 2018/11/15 61 * @Parameters: 62 * @Return: 63 */ 64 @OnClose 65 public void onClose() { 66 copyOnWriteArraySet.remove(this); 67 System.out.println("websocket鏈接斷開, 總數:"+ copyOnWriteArraySet.size()); 68 } 69 70 /** 71 * @Name:onMessage 72 * @Description:測試客戶端發送消息,測試是否聯通 73 * @Author:mYunYu 74 * @Create Date:14:46 2018/11/15 75 * @Parameters: 76 * @Return: 77 */ 78 @OnMessage 79 public void onMessage(String message) { 80 System.out.println("websocket收到客戶端發來的消息:"+message); 81 } 82 83 /** 84 * @Name:onError 85 * @Description:出現錯誤 86 * @Author:mYunYu 87 * @Create Date:14:46 2018/11/15 88 * @Parameters: 89 * @Return: 90 */ 91 @OnError 92 public void onError(Session session, Throwable error) { 93 System.out.println("發生錯誤:" + error.getMessage() + "; sessionId:" + session.getId()); 94 error.printStackTrace(); 95 } 96 97 public void sendMessage(Object object){ 98 //遍歷客戶端 99 for (WebSocketServer webSocket : copyOnWriteArraySet) { 100 System.out.println("websocket廣播消息:" + object.toString()); 101 try { 102 //服務器主動推送 103 webSocket.session.getBasicRemote().sendObject(object) ; 104 } catch (Exception e) { 105 e.printStackTrace(); 106 } 107 } 108 } 109 110 /** 111 * @Name:sendMessage 112 * @Description:用於發送給客戶端消息(羣發) 113 * @Author:mYunYu 114 * @Create Date:14:46 2018/11/15 115 * @Parameters: 116 * @Return: 117 */ 118 public void sendMessage(String message) { 119 //遍歷客戶端 120 for (WebSocketServer webSocket : copyOnWriteArraySet) { 121 System.out.println("websocket廣播消息:" + message); 122 try { 123 //服務器主動推送 124 webSocket.session.getBasicRemote().sendText(message); 125 } catch (Exception e) { 126 e.printStackTrace(); 127 } 128 } 129 } 130 131 /** 132 * @throws Exception 133 * @Name:sendMessage 134 * @Description:用於發送給指定客戶端消息 135 * @Author:mYunYu 136 * @Create Date:14:47 2018/11/15 137 * @Parameters: 138 * @Return: 139 */ 140 public void sendMessage(Integer userID, String message) throws Exception { 141 Session session = null; 142 WebSocketServer tempWebSocket = null; 143 for (WebSocketServer webSocket : copyOnWriteArraySet) { 144 if (webSocket.getUserID() == userID) { 145 tempWebSocket = webSocket; 146 session = webSocket.session; 147 break; 148 } 149 } 150 if (session != null) { 151 //服務器主動推送 152 tempWebSocket.session.getBasicRemote().sendText(message); 153 154 } else { 155 System.out.println("沒有找到你指定ID的會話:{}"+ "; userId:" + userID); 156 } 157 } 158 159 160 161 }
@Resource WebSocketServer webSocket; @Autowired UserService userService;
調用示例:
if(userID>0) { boolean location = userService.getLocation(userID); if(location==false) {//驗證用戶當前不在館內 boolean i = userService.modifyLocation(userID, true); if(i==true) { modelMap.put("successEnter", true); //發消息給客戶端 webSocket.sendMessage(userID, "success"); } }else { modelMap.put("successEnter", false); //發消息給客戶端 webSocket.sendMessage(userID, "fail"); } }else { modelMap.put("successEnter", false); //發消息給客戶端 webSocket.sendMessage(userID, "fail"); }
由於我只寫後端,前端部分小姐姐說看微信的官方文檔就能夠啦~ 連接:在此!微信封裝好了吧,好像不難。小程序
3. 而後終於傳來了喜訊!開心~後端
前端鏈接成功:api
後端輸出記錄:
ps:紅框的1,2,3,4應該是每次鏈接時自增加的sessionid,即上面截圖中返回的socketTaskId,話說用這個來標識用戶應該也能夠。
服務器主動給該客戶端發消息,成功發送!
前期對WebSocket的知識瞭解估計還不夠吧,致使在理解問題的過程當中花費了很多時間。
不過是否是程序員都會有這種錯覺呢?:當你面前有一座大山,你以爲難以跨越,但當你成功翻山越嶺以後,就會以爲這座山不過爾爾?
嘿嘿嘿,下面是學習WebSocket過程當中參考的幾篇博文:
原文出處:https://www.cnblogs.com/codecheng/p/10657530.html