websocket多客户端接收消息_WebSocket之消息接收发送
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
http协议是单向通信,一般由客户端发起请求,然后接收服务端响应。如果要实现客户端实时消息跟新功能如:更新聊天消息,更新邮件信息,更新后台系统员工待办事消息等,传统的做法是基于http协议,然后客户端定时轮询(如每秒访问一次)访问服务端,但是这样就会产生大量无效的http请求,浪费了服务器资源。
而 WebSocket ,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输,客户端可以向服务端发送通信,并且客户端不必轮询请求服务端,服务端如果有消息可以直接发送给客户端。
以下是WebSocket实现聊天室代码示例:
1.集成webSocket
maven添加
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-websocketartifactId> dependency>
添加配置类:WebSocketConfig
@Configurationpublic class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); }}
2.开发WebSocket服务端:
//@ServerEndpoint("/imserver/{userId}") 、@Component即可启用//WebSocket服务//@OnOpen开启连接触发调用,@onClose关闭连接触发调用//,@onMessage接收消息触发掉用@ServerEndpoint("/imserver/{userId}")@Componentpublic class WebSocketServer { /**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/ private static int onlineCount = 0; //缓存每个客户端对应的MyWebSocket对象。 //如果是集群可改成redis或mysql private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>(); /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/ private Session session; /**接收userId*/ private String userId=""; /** * 连接建立成功调用的方法*/ @OnOpen public void onOpen(Session session,@PathParam("userId") String userId) { this.session = session; this.userId=userId; if(webSocketMap.containsKey(userId)){ //如果已有链接则跟新 webSocketMap.remove(userId); webSocketMap.put(userId,this); }else{ //如果新连接存入缓存中 webSocketMap.put(userId,this); //在线人数加 1 addOnlineCount(); } try { //向链接客户端发送链接成功消息 sendMessage("{\"contentText\":\"连接成功\"}"); //跟新连接上的用户的在线人数 if(onlineCount > 0){ webSocketMap.values().forEach(x -> { try { x.sendMessage("{\"onlineCount\":"+onlineCount+"}"); } catch (IOException e) { } }); } } catch (IOException e) { } } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { if(webSocketMap.containsKey(userId)){ //从缓存中移除断开的链接 webSocketMap.remove(userId); //在线人数 - 1 subOnlineCount(); //跟新连接上的用户的在线人数 if(onlineCount > 0){ webSocketMap.values().forEach(x -> { try { x.sendMessage("{\"onlineCount\":"+onlineCount+"}"); } catch (IOException e) { e.printStackTrace(); } }); } } } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息*/ @OnMessage public void onMessage(String message, Session session) { //可以群发消息 //消息保存到数据库、redis if(!StringUtils.isEmpty(message)){ try { //解析发送的报文 JSONObject jsonObject = JSON.parseObject(message); //追加发送人(防止串改) jsonObject.put("fromUserId",this.userId); String toUserId=jsonObject.getString("toUserId"); //传送给对应toUserId用户的websocket if((!StringUtils.isEmpty(toUserId))&&webSocketMap.containsKey(toUserId)){ //向客户端发送消息 webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString()); }else{ //否则不在这个服务器上,发送到mysql或者redis } }catch (Exception e){ e.printStackTrace(); } } } /** * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { error.printStackTrace(); } /** * 实现服务器主动推送 */ public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } /** * 发送自定义消息 * */ public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException { if((!StringUtils.isEmpty(userId))&&webSocketMap.containsKey(userId)){ webSocketMap.get(userId).sendMessage(message); }else{ } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; }}
3.客户端WebSocket开发
目前 HTML5 以支持WebSocket
var Socket = new WebSocket(url, [protocol] );WebSocket相关事件:open Socket.onopen 连接建立时触发message Socket.onmessage 客户端接收服务端数据时触发error Socket.onerror 通信发生错误时触发close Socket.onclose 连接关闭时触发
<html><head> <meta charset="utf-8"> <title>websocket通讯title>head><script src="./jquery-1.7.2.js">script><script> var socket; function openSocket() { if(typeof(WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket"); }else{ console.log("您的浏览器支持WebSocket"); //实现化WebSocket对象,指定要连接的服务器地址与端口 建立连接 //等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25"); //var socketUrl="${request.contextPath}/im/"+$("#userId").val(); var socketUrl="http://localhost:9999/imserver/"+$("#userId").val(); socketUrl=socketUrl.replace("https","ws").replace("http","ws"); console.log(socketUrl); if(socket!=null){ socket.close(); socket=null; } socket = new WebSocket(socketUrl); //打开事件 socket.onopen = function() { console.log("websocket已打开"); //socket.send("这是来自客户端的消息" + location.href + new Date()); }; //获得消息事件 socket.onmessage = function(msg) { console.log(msg.data); //发现消息进入 开始处理前端触发逻辑 $("#contentText").val($.parseJSON(msg.data).contentText); $("#onlineCount").val($.parseJSON(msg.data).onlineCount); }; //关闭事件 socket.onclose = function() { console.log("websocket已关闭"); }; //发生了错误事件 socket.onerror = function() { console.log("websocket发生了错误"); } } } function sendMessage() { if(typeof(WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket"); }else { console.log("您的浏览器支持WebSocket"); var inputText = $("#inputText").val(); console.log('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+inputText+'"}'); socket.send('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+inputText+'"}'); } }script><body><p>【在线人数】:<div><input id="onlineCount" name="onlineCount" type="text" >div><p>【userId】:<div><input id="userId" name="userId" type="text" value="10">div><p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="20">div><p>【message】:<div> <textarea id="contentText" name="contentText" type="text" value="hello websocket">textarea> div><p>【input】:<div><input id="inputText" name="inputText" type="text" >div><p>【操作】:<div><a onclick="openSocket()">开启socketa>div><p>【操作】:<div><a onclick="sendMessage()">发送消息a>div>body>html>
4.演示:
websocket多客户端接收消息_WebSocket之消息接收发送相关推荐
- ios个推透传消息json接收不到_消息通讯——Websocket
说起即时通讯大家应该都听过,像各种聊天软件用到的即时通讯技术是最多的.另外开发过程中实现消息推送最传统的做法就是轮询,即按照特定时间间隔由浏览器对服务器发送请求,以获取最新消息,这种传统模式带来很明显 ...
- python3.6 websocket异步高并发_在Python3.6上的websocket客户端中侦听传入消息时出现问题...
我正在尝试使用websockets包在Python上构建一个websockets客户端:Websockets 4.0 API 我使用这种方式而不是示例代码,因为我想创建一个websocket客户机类对 ...
- 客户端关闭服务器收到消息推送消息,【网络编程】——WebSocket打开和关闭通道,消息发送...
HTML5给Web浏览器带来了全双工TCP链接WebSocket标准服务器的能力.浏览器和可以与服务器创建链接,经过已创建的通讯信道来发送和接收数据而不须要由HTTP协议入额外的开销.javascri ...
- 未能分析从服务器收到的消息,WebSocket Javascript客户端未收到来自服务器的消息...
我已经在本地GlassFish 4.1服务器上部署了Java Web应用程序,该服务器实现了与Web客户端互操作的WebSockets.我能够通过套接字成功执行客户端到服务器的通信,但由于某种原因,服 ...
- C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密
在上篇随笔<C#开发微信门户及应用(19)-微信企业号的消息发送(文本.图片.文件.语音.视频.图文消息等)>介绍了有关企业号的消息发送,官方特别声明消息是不用加密发送的.但是在回调的服务 ...
- 公众号 接收规则 消息_微信公众平台 发送模板消息(Java接口开发)
前言:最近一直再弄微信扫码推送图文消息和模板消息发送,感觉学习到了不少东西.今天先总结一下微信公众平台模板消息的发送.因为这个自己弄了很久,开始很多地方不明白,所以今天好好总结一下. 微信公众平台技术 ...
- 通过websocket抓取斗鱼弹幕和礼物消息
1.斗鱼弹幕协议 到斗鱼官方开放平台看斗鱼通讯协议,网址"斗鱼开放平台",登录后可查看 所以根据斗鱼协议做编码函数: 1 def msg_encode(msg):2 #消息以 \0 ...
- 【一学就会的ROS基础入门教程 】03-1 ROS基础编程:ROS工作空间的创建、话题topic的发布与接收、以及话题消息的自定义使用
[一学就会的ROS基础入门教程 ]03-1 ROS基础编程:ROS工作空间的创建.话题topic的发布与接收.以及话题消息的自定义使用 文前白话 1.创建工作空间与功能包 关于工作空间的介绍 创建开发 ...
- Netty简单实现客户端与服务端收发消息
Netty简单实现客户端与服务端收发消息 这个小案例主要是实现netty收发消息,分为客户端,及服务端,以及包含了相关状态处理,主要的代码会放在最后 gitHub 地址上,有需要可以看一下 首先来简单 ...
最新文章
- php如何隐藏入口文件,PHP怎样隐藏入口文件
- C# 设置Menustrip提示框的显示
- 学习笔记Hadoop(一)—— Hadoop介绍(1)——认识大数据
- Topo系统的益处和帮助
- 航空企业如何用「AI利器」提升乘客体验
- 一键导出/备份「有道云笔记」工具
- HDU - 3746 Cyclic Nacklace(KMP的next数组判循环节)
- 项目测试基础:白盒测试相关知识笔记
- .NET开发框架(一)-框架介绍与视频演示
- java监听双按键_java 键盘监听 按一次键监听到两次
- java大致了解_学习Java第一天,大致了解
- 11.高性能MySQL --- 可扩展MySQL
- OpenGL ES总结(四)OpenGL 渲染视频画面
- vscode通过ssh远程连接服务器
- ImageNet 2012 中文标签(Chinese Labels)
- HorizontalScrollView+recyclerView
- 抖音吸粉_抖音吸粉六大技巧
- java无效的参数_java.sql.SQLException: 调用中无效的参数
- 服务器usb驱动安装系统安装失败怎么办,usb驱动安装不成功,小编教你usb驱动安装失败的解决方法...
- 微型计算机原理及接口技术张云龙答案,电子职业技能训练报告2.docx
热门文章
- Veeam FAQ系列转载(二)
- Spring Boot学习总结(19)——使用Redisson实现分布式锁
- Beetl学习总结(4)——Web集成
- 50道编程小题目之【无重复的三位数】
- php 时间戳存储 原因,将php文件中的unix时间戳存储到mysql中(store unix timestamp from php file into mysql)...
- requests模块报错:Use body.encode('utf-8') if you want to send it encoded in UTF-8.
- 为什么DevOps和SRE职位这么难招人?
- Windows安全不能靠本地管理员权限
- synchronized方法与synchronized代码块的区别
- mysql-5.6.24-win32.zip 下载 安装 配置 创建数据库