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