SpringBoot2.x服务器端主动推送技术
一.服务端推送常用技术介绍
服务端主流推送技术:websocket、SSE等
1.客户端轮询:ajax定时拉取后台数据
js setInterval定时函数 + ajax异步加载 定时向服务器发送请求
服务器压力会较大
2.服务端主动推送:websocket《推荐使用》
全双工即双向通讯,本质上是一个额外的TCP连接,建立和关闭时握手使用http协议,其他数据传输不使用http协议,更加复杂一些,适用于需要进行复杂双向数据通讯的场景,支持大部分主流浏览器。
开发成本较高,适用性较好,适用于聊天功能等。
WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
客户端代码
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/WebSocketTest/websocket");
}
else {
alert('当前浏览器 Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function () {
setMessageInnerHTML("WebSocket连接发生错误");
};
//连接成功建立的回调方法
websocket.onopen = function () {
setMessageInnerHTML("WebSocket连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function (event) {
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
websocket.onclose = function () {
setMessageInnerHTML("WebSocket连接关闭");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
closeWebSocket();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
//发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
服务端代码
/**
* websocket服务
* @author like
*
*/
@ServerEndpoint("/websocket")
public class WebsocketTest {
private static int onlineCount=0;//记录当前在线人数
//确保线程安全
private static CopyOnWriteArraySet<WebsocketTest> webSocketSet=new CopyOnWriteArraySet<WebsocketTest>();
private Session session;
@OnOpen
public void onOpen(Session session){
this.session=session;
webSocketSet.add(this);
addOnlineCount();
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
}
@OnClose
public void OnClose(){
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());    
}
@OnMessage
public void OnMessage(String message, Session session){
System.out.println("来自客户端的消息:" + message);
//群发消息
for(WebsocketTest item: webSocketSet){
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
@OnError
public void OnError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();    
}
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebsocketTest.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebsocketTest.onlineCount--;
}
}
3.服务端主动推送:SSE(Server Send Event)
简介:
SSE(Server-Sent Events,服务器发送事件)是围绕只读Comet 交互推出的API 或者模式。
SSE API允许网页获得来自服务器的更新(HTML5),用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。
服务器响应的MIME类型必须是text/event-stream,而且是浏览器中的JavaScript API 能解析格式输出。
SSE 支持短轮询、长轮询和HTTP 流,而且能在断开连接时自动确定何时重新连接。
SSE是html5新标准,用来实现从服务端实时推送数据导浏览器端
直接建立在当前http协议上,本质上是保持一个http长连接,轻量级协议
适用于简单的服务器数据推送场景,使用服务器推送事件
学习资料:https://www.w3school.com.cn/html5/html_5_serversentevents.asp
前端代码
客户端只需要直接使用**window.EventSource**对象,然后调用该对象的相应方法即可。
//判断是否支持SSE
if('EventSource' in window){
//初始化SSE
var url="http:localhost:8080/test/push";
var source=new EventSource(url);
//开启时调用
source.onopen=(event)=>{
console.log("开启SSE");
}
//监听message事件
source.onmessage=(event)=>{
var data=event.data;
$("body").append($("<p>").text(data));
}
//监听like事件
source.addEventListener('like',function(event){
var data=event.data;
$("body").append($("<p>").text(data));
},false);
//发生异常时调用
source.onerror=(event)=>{
console.log(event);
}
服务端代码
由于SSE是http请求,但是又限定是一个长连接,所以要设置MIME类型为text/event-stream。返回的为字符串。
/**
* SSE后台controller
* @author like
*
*/
@Controller
@RequestMapping(value="/test")
public class TestSSEController {
@ResponseBody
@RequestMapping(value="/push",produces="text/event-stream;charset=UTF-8")
public String push(HttpServletResponse res){
res.setHeader("Access-Control-Allow-Origin","*");
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String nowDate=sdf.format(date);
return "data: 我是一个data 现在时间是"+nowDate+" \nevent:like\n retry:5000\n\n";
} 
}
消息体格式
服务器向浏览器发送的 SSE 数据,必须是 UTF-8 编码的文本;
每一次发送的信息,由若干个message组成,每个message之间用\n\n分隔。每个message内部由若干行组成;
格式
[field]:value\n
其中field可以为四种
- data
 - event
 - id
 - retry
 
data代表数据,event代表事件名称,id代表id,retry代表多少时间轮训一次。
所以我的服务端写的消息就可以翻译为:事件名称为**like**,数据为**我是一个data 现在时间是+当前时间**,每5秒轮训一次
data: 我是一个data 现在时间是"+nowDate+" \nevent:like\n retry:5000\n\n
SSE与WebSocket有相似功能,都是用来建立浏览器与服务器之间的通信渠道。两者的区别在于:
- WebSocket是全双工通道,可以双向通信,功能更强;SSE是单向通道,只能服务器向浏览器端发送。
 - WebSocket是一个新的协议,需要服务器端支持;SSE则是部署在 HTTP协议之上的,现有的服务器软件都支持。
 - SSE是一个轻量级协议,相对简单;WebSocket是一种较重的协议,相对复杂。
 - SSE默认支持断线重连,WebSocket则需要额外部署。
 - SSE支持自定义发送的数据类型。
 - SSE不支持CORS 参数url就是服务器网址,必须与当前网页的网址在同一个网域(domain),而且协议和端口都必须相同。
 
SpringBoot2.x服务器端主动推送技术的更多相关文章
- 【SpringBoot】服务器端主动推送SSE技术讲解
		
=====================16.高级篇幅之SpringBoot2.0服务器端主动推送SSE技术讲解 ============================ 1.服务端推送常用技术介绍 ...
 - 服务器端实时推送技术之SseEmitter的用法
		
这是SpringMVC提供的一种技术,可以实现服务端向客户端实时推送数据.用法非常简单,只需要在Controller提供一个接口,创建并返回SseEmitter对象,发送数据可以在另一个接口调用其se ...
 - Web服务器主动推送技术
		
HTTP协议遵循经典的客户端-服务器模型,客户端发送一个请求,然后等待服务器端的响应,服务器端只能在接收到客户端的请求之后进行响应,不能主动的发送数据到客户端. 客户端想要在不刷新页面的情况下实时获取 ...
 - HTML5中的SSE(服务器推送技术)
		
本文原链接:https://cloud.tencent.com/developer/article/1194063 SSE技术详解:一种全新的HTML5服务器推送事件技术 前言 概述 基本介绍 与We ...
 - PHP ServerPush (推送) 技术的探讨
		
2016年11月29日17:51:03 转自:http://www.cnblogs.com/hnrainll/archive/2013/05/07/3064874.html 需求: 我想做个会员站内通 ...
 - comet基于HTTP长连接技术(java即时通信,推送技术详解)
		
服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息,服务器发送一批数据,浏览器显示消息,同时保证与服务器的连接,当服务器需要再一次的发送数据,浏览器显示数据并保持连接. comet基 ...
 - Web端服务器推送技术原理分析及dwr框架简单的使用
		
1 背景 “服务器推送技术”(ServerPushing)是最近Web技术中最热门的一个流行术语.它是继“Ajax”之后又一个倍受追捧的Web技术.“服务器推送技术”最近的流行跟“Ajax ”有着密切 ...
 - DWR推送技术
		
“服务器推送技术”(ServerPushing)是最近Web技术中最热门的一个流行术语.它是继“Ajax”之后又一个倍受追捧的Web技术.“服务器推送技术”最近的流行跟“Ajax ”有着密切的关系. ...
 - 深入了解 Dojo 的服务器推送技术
		
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...
 
随机推荐
- 什么是依赖注入 IoC
			
设计原则:依赖注入原则 依赖倒置原则,是一种程序设计模式的原则 高层模块不应该依赖底层模块,二者都应该依赖其抽象. 抽象不应该依赖细节,细节应该依赖抽象.依赖导致原则很好的体现了“面向接口编程”的思想 ...
 - 【C#】使用C# 读取Http的Post数据
			
private string Post(string num) { Encoding myEncoding = Encoding.GetEncoding("gb2312"); // ...
 - EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器和EasyDSS云平台异同
			
背景分析 不同于EasyDSS流媒体服务器与EasyDSS流媒体解决方案(EasyDSS流媒体解决方案就是通过EasyDSS流媒体服务器完善业务层研发而来),EasyDSS流媒体服务器和EasyDSS ...
 - vue-loader会缓存node_modules中依赖模块
			
问题如下: https://github.com/vuejs/vue-cli/issues/3635 截止到vue cli3还没有解决 手动删除node_modules下的.cache文件夹可以解决这 ...
 - General VDPConfig对讲配置工具
			
General VDPConfig大华楼宇对讲配置工具是ConfigTool的一个对讲模块,主要服务对象为可视对讲的门口机和室内机,大华可视对讲在独户应用中,利用了自身在视频监控领域的优势,充分整合了 ...
 - imagettftext(): Could not read font
			
imagettftext(): Could not read font 1 确认FreeType Version ( 2以上版本) 2 确认字体路径,要是绝对路径的 3 确认 php.ini 配置 开 ...
 - WIFI-Direct(Wifi直连)、AirPlay、DLAN、Miracast功能介绍
			
不知道大家对无线同屏技术有多少了解,当这种技术普及的时候,我想我们的工作与生活又会方便很多吧!下面是目前三种主流同屏技术的介绍: 目前这种将终端信号经由WiFi传输到电视.电视盒的技术有三种:DLNA ...
 - Locust 性能测试工具安装使用说明
			
1. 介绍 它是一个开源性能测试工具.使用 Python 代码来定义用户行为.用它可以模拟百万计的并发用户访问你的系统. 性能工具对比 LoadRunner 是非常有名的商业性能测试工具,功能 ...
 - 【转帖】HBase简介(梳理知识)
			
HBase简介(梳理知识) https://www.cnblogs.com/muhongxin/p/9471445.html 一. 简介 hbase是bigtable的开源山寨版本.是建立的hdf ...
 - JPA中JpaRepository的使用
			
JAP中JpaRepository的使用方法 转载:https://www.cnblogs.com/amberbar/p/10261599.html转载:https://www.cnblogs.com ...