热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

websocket实现服务端消息推送

WebSocket全双工通信与消息推送BS结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化web

WebSocket全双工通信与消息推送
B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链接,但不容易直接完成实时的消息推送功能,如聊天室、后台信息提示、实时更新数据等功能,但通过polling、Long polling、长链接以及HTML5中定义的WebSocket能完成该功能需要。

一、Socket简介
Socket又称‘套接字‘,应用程序通常通过‘套接字‘向网络发出请求或者应答网络请求。Socket可以实现应用程序间网络通信。

Socket可以使用TCP/IP协议或者UDP协议
TCP/IP协议
TCP/IP协议是目前最为广泛的协议,是构成Internet国际互联网协议的最为基础的协议,由TCP和IP协议组成。
TCP协议:是面向连接的,可靠的、基于字节流的传输层通信协议,负责数据的可靠性传输问题。
IP协议:用于报文交换网络的一种面向数据的协议,主要负责给每台网络设备一个网络地址,保证数据传输到正确的目的地。
UDP协议
无连接、不可靠、基于报文的传输层协议,优点是发送后不用管,速度比TCP快。

二、WebSocket即简介与消息推送

B/S架构的系统多使用HTTP协议

HTTP协议的特点
1无状态协议
2用于通过Internet发送请求消息和响应消息
3使用端口接收和发送消息,默认端口80

HTTP协议决定了服务器与客户端之间的连接方式,无法直接实现双向通信与消息推送,一些变相的解决办法:
轮询polling:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。请求中大半是无用的,浪费带宽和服务器资源。
长轮训Long polling:客户端定时向服务器发送Ajax请求,服务器接到请求后Hold住连接,直到有消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。在无消息的情况下不会频繁的请求,耗资少,但是服务器hold住连接会消耗资源,返回数据无保障。
长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。 优点:消息即时到达,不发无用请求;管理起来也相对便。 缺点:服务器维护一个长连接会增加开销。 实例:Gmail聊天
WebSocket:是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
特点:
事件驱动
异步
使用ws或者wss协议的客户端socket
能够实现真正意义上的推送功能

缺点:
少部分浏览器不支持,浏览器支持的程度与方式有区别。
这里写图片描述

三、WebSocket客户端
websocket允许通过Javascript建立与远程服务器的连接,从而实现客户端与服务器间双向的通信。在websocket中有两个方法:
1、send() 向远程服务器发送数据
2、close() 关闭该websocket链接
websocket同时还定义了几个监听函数
1、onopen 当网络连接建立时触发该事件
2、onerror 当网络发生错误时触发该事件
3、onclose 当websocket被关闭时触发该事件
4、onmessage 当websocket接收到服务器发来的消息的时触发的事件,也是通信中最重要的一个监听事件。msg.data
websocket还定义了一个readyState属性,这个属性可以返回websocket所处的状态:
1、CONNECTING(0) websocket正尝试与服务器建立连接
2、OPEN(1) websocket与服务器已经建立连接
3、CLOSING(2) websocket正在关闭与服务器的连接
4、CLOSED(3) websocket已经关闭了与服务器的连接

websocket的使用
websocket的url开头是ws,如果需要ssl加密可以使用wss,当我们调用websocket的构造方法构建一个websocket对象(new WebSocket(url))的之后,就可以进行即时通信了。

前后台使用websocket实例

1前台实现

来源:http://www.cnblogs.com/likun10579/p/5594828.html

1 connect:function() {2 var webSocketIP = window.CRM_CONFIG.WebSocketIP;3 var target = 'ws://'+webSocketIP+'/websocket';4 if ('WebSocket' in window) {5 ws = new WebSocket(target);6 } else if ('MozWebSocket' in window) {7 ws = new MozWebSocket(target);8 } else {9 return;
10 }
11 ws.onopen = function () {
12 console.log('Info: WebSocket connection opened.');
13 document.getElementById("wsMsg").style.display = "block";
14 };
15 var self = this;
16 ws.onmessage = function (event) {
17 if('您有如下工单需要及时处理:'!= event.data) {
18 self.setState({wsMessage: event.data})
19 document.getElementById("wsMsg").style.display = "block";
20 }else{
21 document.getElementById("wsMsg").style.display = "none";
22 }
23 };
24
25


26
27 {this.state.wsMessage}
28

后台实现
2、pom.xml依赖

1 2 3 javax.servlet4 javax.servlet-api5 3.1.06 7 8 org.springframework9 spring-websocket
10 ${spring.version}
11

3、spring.xml配置




4、java代码

package com.oasis.crm.controller.websocket;
import com.oasis.crm.dao.biz.user.UserDao;
import com.oasis.crm.model.biz.user.User;
import com.oasis.crm.service.biz.order.AcceptedWorkOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.Timer;
import java.util.TimerTask;/*** 推送即将要处理完成的受理单给处理人*/
@RequestMapping("/websocket")
public class WebsocketEndPoint extends TextWebSocketHandler {@Autowiredprivate AcceptedWorkOrderService acceptedWorkOrderService;@Autowiredprivate UserDao userDao;private Timer timer;@Overrideprotected void handleTextMessage(WebSocketSession session,TextMessage message) throws Exception {if(!session.isOpen()){timer.cancel();return;}super.handleTextMessage(session, message);session.sendMessage(message);}@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {String loginUserName = session.getPrincipal().getName();User user = userDao.findUserByLoginName(loginUserName);timer = new Timer(true);long delay = 0;OrderTimeTask orderTimeTask = new OrderTimeTask(user,session);timer.schedule(orderTimeTask,delay, 60000);// 设定指定的时间time,此处为1分钟}class OrderTimeTask extends TimerTask{private User user;private WebSocketSession session;public OrderTimeTask(User user,WebSocketSession session){this.user = user;this.session = session;}@Overridepublic void run() {try {String reminder = acceptedWorkOrderService.getLastReminderOrder(user.getId());TextMessage textMessage = new TextMessage(reminder);handleMessage(session,textMessage);} catch (Exception e){e.printStackTrace();}}}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {System.out.println("Connection Closed!");}}/*** 自定义的拦截器*/package com.oasis.crm.controller.websocket;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;import java.util.Map;public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {@Overridepublic boolean beforeHandshake(ServerHttpRequest request,ServerHttpResponse response, WebSocketHandler wsHandler,Map attributes) throws Exception {return super.beforeHandshake(request, response, wsHandler, attributes);}@Overridepublic void afterHandshake(ServerHttpRequest request,ServerHttpResponse response, WebSocketHandler wsHandler,Exception ex) {super.afterHandshake(request, response, wsHandler, ex);}}

前端通过pull方式拉取数据代码

setInterval(()=> {this.getReminders();}, 300000);getReminders(){$.getJSON(Remote.acceptedWorkOrder.reminderOrders,packVo=>{this.setState({wsMessage:packVo.vo});});if('您有如下工单需要及时处理:'!= this.state.wsMessage&&''!=this.state.wsMessage){document.getElementById("wsMsg").style.display = "block";}else{document.getElementById("wsMsg").style.display = "none";}}

总结
没有其他能像 WebSocket 一样实现双向通信的技术了,迄今为止,大部分开发者还是使用 Ajax 轮询来实现,但这是个不太优雅的解决办法,WebSocket 虽然用的人不多,可能是因为协议刚出来的时候有安全性的问题以及兼容的浏览器比较少,但现在都有解决。如果你有这些需求可以考虑使用 WebSocket:

1 、多个用户之间进行交互;

2、需要频繁地向服务端请求更新数据。

比如弹幕、消息订阅、多玩家游戏、协同编辑、股票基金实时报价、视频会议、在线教育等需要高实时的场景。

参考文章

这三篇分别是原理和场景上深度解析websocket的好文

1、一文读懂 WebSocket 通信过程与实现
https://blog.csdn.net/zhusongziye/article/details/80316127

2、Websocket:看完让你彻底搞懂Websocket原理 即时消息通讯
https://blog.csdn.net/qq_38047600/article/details/80024696

3、websocket可以是纯Java实现,也可以整合Maven工程SSM框架实现,前端都是html或jsp的网页进行websocket使用与实现。
https://blog.csdn.net/qq_38047600/article/details/80024696


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • charles3.11.1抓https包
    结论先行:用的是安卓测试机,没加固之前的生产环境的安装包,可以抓到https请求加固之后的包【也就是要上应用市场的包】,抓不到https请求电脑上的操作:1.安装证书【电脑上安装了 ... [详细]
  • tomcat的log文件夹下有以下几种日志:1、catalina.YYYY-MM-DD.logcatalina引擎输出的日志;catalina是tomc ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 介绍一款好用的内网穿透工具FRP
    本文介绍了一款好用的内网穿透工具FRP,它是一个使用Go语言开发的高性能的反向代理应用。FRP支持多种协议类型,并且可以根据域名进行路由转发。 ... [详细]
  • POCOCLibraies属于功能广泛、轻量级别的开源框架库,它拥有媲美Boost库的功能以及较小的体积广泛应用在物联网平台、工业自动化等领域。POCOCLibrai ... [详细]
  • 现在比较流行使用静态网站生成器来搭建网站,博客产品着陆页微信转发页面等。但每次都需要对服务器进行配置,也是一个重复但繁琐的工作。使用DockerWeb,只需5分钟就能搭建一个基于D ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
  • Ansem 最新雄文:软着陆后,加密市场下阶段趋势与核心叙事
    市场最糟糕的时候已经过去,以太坊合并前不太会看到新的低点;但仍需来自关注宏观市场的不确定风险。撰文:Ansem ... [详细]
  • OAuth2.0指南
    引言OAuth2.0是一种应用之间彼此访问数据的开源授权协议。比如,一个游戏应用可以访问Facebook的用户数据,或者一个基于地理的应用可以访问Foursquare的用户数据等。 ... [详细]
  • 基于SSL的mysql服务器的主从架构实现说明:本文选用172.16.22.1作为主服务器,172.16.22.3作为从服务器从服务器的mysql软件版 ... [详细]
author-avatar
Z先生286_158
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有