您的位置 首页 > 数码极客

[websocket如何传参]websocket传多个参数!

WebSocket 协议是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工 (full-duplex) 通信—允许服务器主动发送信息给客户端。

为什么需要Websocket?

大家都知道以前客户端想知道服务端的处理进度,要不停地使用 Ajax 进行轮询,让浏览器隔个几秒就向服务器发一次请求,这对服务器压力较大。另外一种轮询就是采用 long poll 的方式,这就跟打电话差不多,没收到消息就一直不挂电话,也就是说,客户端发起连接后,如果没消息,就一直不返回 response 给客户端,连接阶段一直是阻塞的。

而 WebSocket 解决了 HTTP 的这几个难题。当服务器完成协议升级后( HTTP -> WebSocket ),服务端可以主动推送信息给客户端,解决了轮询造成的同步延迟问题。由于 WebSocket 只需要一次 HTTP 握手,服务端就能一直与客户端保持通信,直到关闭连接,这样就解决了服务器需要反复解析 HTTP 协议,减少了资源的开销。

现在通过 SpringBoot 集成 WebSocket 来实现前后端通信。

集成 WebSocket 实现前后端通信

项目代码结构图

依赖导入

S 对 WebSocket 的支持简直太棒了,直接就有包可以引入 。

<dependency> <groupId>org.;/groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>

配置 WebSocketConfig

启用WebSocket的支持也是很简单,将serverEndpointExporter对象注入到容器中。

package com.; import org.; import org.; import org.; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }

WebSocket 服务端 WebSocketServer

因为 WebSocket 是类似客户端服务端的形式(采用ws协议),那么这里的 WebSocketServer 其实就相当于一个 ws协议的 Controller。直接 @ServerEndpoint("/websocket") 、@Component 启用即可,然后在里面实现@OnOpen , @onClose ,@onmessage等方法

package com.; import lombok.ex; import org.; import javax.websocket.*; import javax.web; import javax.web; import java.io.IOException; import java.u; @Component @ServerEndpoint("/websocket/{sid}") @Slf4j public class WebSocketServer { /** * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 */ private static int onlineCount = 0; /** * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 */ private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>(); /** * 与某个客户端的连接会话,需要通过它来给客户端发送数据 */ private session session; /** * 接收sid */ private String sid=""; /** * 连接建立成功调用的方法 **/ @OnOpen public void onOpen(Session session,@PathParam("sid") String sid) { = session; //加入set中 webSocke(this); //在线数加1 addOnlineCount(); log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount()); ; try { sendMessage("连接成功"); } catch (IOException e) { log.error("websocket IO异常"); } } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { //从set中删除 webSocke(this); //在线数减1 subOnlineCount(); log.info("有一连接关闭!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 **/ @OnMessage public void onMessage(String message, Session session) { log.info("收到来自窗口"+sid+"的信息:"+message); //群发消息 for (WebSocketServer item : webSocketSet) { try { i(message); } catch (IOException e) { e.printStackTrace(); } } } /** * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); } /** * 实现服务器主动推送 */ public void sendMessage(String message) throws IOException { .getBasicRemote().sendText(message); } /** * 群发自定义消息 * */ public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException { log.info("推送消息到窗口"+sid+",推送内容:"+message); for (WebSocketServer item : webSocketSet) { try { //这里可以设定只推送给这个sid的,为null则全部推送 if(sid==null) { i(message); }else i(sid)){ i(message); } } catch (IOException e) { continue; } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocke; } public static synchronized void subOnlineCount() { WebSocke; } }

消息推送

至于推送新信息,可以再自己的 Controller 写个方法调用 WebSocke() 即可

package com.; import org..*; import org.; import java.io.IOException; @RestController @RequestMapping("/checkcenter") public class CheckCenterController { /** * 页面请求 * @param cid * @return */ @GetMapping("/socket/{cid}") public ModelAndView socket(@PathVariable String cid) { ModelAndView mav=new ModelAndView("/socket"); mav.addObject("cid", cid); return mav; } /** * 推送数据接口 * @param cid * @param message * @return */ @ResponseBody @RequestMapping("/socket/push/{cid}") public String pushToWeb(@PathVariable String cid,String message) { try { WebSocke(message,cid); } catch (IOException e) { e.printStackTrace(); return "error:"+cid+"#"+e.getMessage(); } return "success:"+cid; } }

页面发起socket请求

然后在页面用js代码调用 socket,当然,太古老的浏览器是不行的,一般新的浏览器或者谷歌浏览器是没问题的。还有一点,记得协议是ws的哦。直接在浏览器控制台开启连接。

var socket; if(typeof(WebSocket) == "undefined") { con("您的浏览器不支持WebSocket"); }else{ con("您的浏览器支持WebSocket"); //实现化WebSocket对象,指定要连接的服务器地址与端口 建立连接 socket = new WebSocket("ws://localhost:8080/websocket/20"); //打开事件 = function() { con("Socket 已打开"); ("这是来自客户端的消息" + loca + new Date()); }; //获得消息事件 = function(msg) { con); //发现消息进入 开始处理前端触发逻辑 }; //关闭事件 = function() { con("Socket已关闭"); }; //发生了错误事件 = function() { alert("Socket发生了错误"); //此时可以尝试刷新页面 } //离开页面时,关闭socket 中已经被废弃,3.0中已经移除 // $(window).unload(function(){ // (); //}); }

运行效果

现在可以在浏览器开启连接,通过客户端调用接口服务端就可以向浏览器发送消息。

现在打开两个页面开启两个连接:

  • socket = new WebSocket("ws://localhost:8080/websocket/20") ;
  • socket = new WebSocket("ws://localhost:8080/websocket/22") ;

向前端推送数据:

  • http://localhost:8080/checkcenter/socket/push/20?message=Hello
  • http://localhost:8080/checkcenter/socket/push/22?message=HelloWorld

可以看到服务端已经将消息推送给了客户端

而客户端也收到了消息

先打开页面,指定cid,启用socket接收,然后再另一个页面调用刚才Controller封装的推送信息的方法到这个cid的socket,即可向前端推送消息。

后续

serverEndpointExporter 错误

org.: Error creating bean with name ‘serverEndpointExporter’ defined in class path resource [com/xxx]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.web not available

如果 tomcat 部署一直报这个错,请移除 WebSocketConfig 中 @Bean ServerEndpointExporter 的注入 。

ServerEndpointExporter 是由 Spring 官方提供的标准实现,用于扫描 ServerEndpointConfig 配置类和@ServerEndpoint 注解实例。使用规则也很简单:

1、如果使用默认的嵌入式容器 比如Tomcat 则必须手工在上下文提供ServerEndpointExporter。

2、如果使用外部容器部署war包,则不需要提供提供ServerEndpointExporter,因为此时SpringBoot默认将扫描 服务端的行为交给外部容器处理,所以线上部署的时候要把WebSocketConfig中这段注入bean的代码注掉。

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“websocket如何传参,websocket传多个参数,websocket,传参,websocket前端传参,websocket传参数,websocket如何”边界阅读