一.服务端推送常用技术介绍

  服务端主流推送技术: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可以为四种

  1. data
  2. event
  3. id
  4. 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服务器端主动推送技术的更多相关文章

  1. 【SpringBoot】服务器端主动推送SSE技术讲解

    =====================16.高级篇幅之SpringBoot2.0服务器端主动推送SSE技术讲解 ============================ 1.服务端推送常用技术介绍 ...

  2. 服务器端实时推送技术之SseEmitter的用法

    这是SpringMVC提供的一种技术,可以实现服务端向客户端实时推送数据.用法非常简单,只需要在Controller提供一个接口,创建并返回SseEmitter对象,发送数据可以在另一个接口调用其se ...

  3. Web服务器主动推送技术

    HTTP协议遵循经典的客户端-服务器模型,客户端发送一个请求,然后等待服务器端的响应,服务器端只能在接收到客户端的请求之后进行响应,不能主动的发送数据到客户端. 客户端想要在不刷新页面的情况下实时获取 ...

  4. HTML5中的SSE(服务器推送技术)

    本文原链接:https://cloud.tencent.com/developer/article/1194063 SSE技术详解:一种全新的HTML5服务器推送事件技术 前言 概述 基本介绍 与We ...

  5. PHP ServerPush (推送) 技术的探讨

    2016年11月29日17:51:03 转自:http://www.cnblogs.com/hnrainll/archive/2013/05/07/3064874.html 需求: 我想做个会员站内通 ...

  6. comet基于HTTP长连接技术(java即时通信,推送技术详解)

    服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息,服务器发送一批数据,浏览器显示消息,同时保证与服务器的连接,当服务器需要再一次的发送数据,浏览器显示数据并保持连接. comet基 ...

  7. Web端服务器推送技术原理分析及dwr框架简单的使用

    1 背景 “服务器推送技术”(ServerPushing)是最近Web技术中最热门的一个流行术语.它是继“Ajax”之后又一个倍受追捧的Web技术.“服务器推送技术”最近的流行跟“Ajax ”有着密切 ...

  8. DWR推送技术

    “服务器推送技术”(ServerPushing)是最近Web技术中最热门的一个流行术语.它是继“Ajax”之后又一个倍受追捧的Web技术.“服务器推送技术”最近的流行跟“Ajax ”有着密切的关系. ...

  9. 深入了解 Dojo 的服务器推送技术

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

随机推荐

  1. An unexpected exception occurred while binding a dynamic operation 错误的一种情况

    这种错误,出现在dynamic传值的时候,无法动态访问变量. 出错原因是: 使用了嵌套类,class里面又定义了class

  2. [Go] 环境变量,模块化与基础语法

    [环境变量] 安装完 go 之后,设置必要环境变量: export GOPATH=/home/wc/go-lab export GO111MODULE=on export GOPROXY=https: ...

  3. mysql语句笔记

    创建数据库 create database name(自定义): #创建一个数据库   name自己取 create database if not exists name() default cha ...

  4. 【LOJ523】[LibreOJ β Round #3]绯色 IOI(悬念)(霍尔定理_基环树)

    题目 LOJ523 官方题解 分析 由于某些原因,以下用「左侧点」和「右侧点」分别代替题目中的「妹子」和「男生」. 根据题意,显然能得出一个左侧点只能向一个或两个右侧点连边.这似乎启发我们把左侧点不看 ...

  5. 【转】pdf文件自动切白边

    pdf文件自动剪裁(自动切白边) FROM:http://www.ai7.org/wp/html/754.html 可能用到的环境.工具:Ubuntu 10.04+TeXLive 2008+pdfcr ...

  6. Linux安装zookeeper3.5.6

    依赖JRE[我这边是JRE8] 一,先在https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/下载apache-zookeeper- ...

  7. PHP设计模式 - 备忘录模式

    备忘录模式又叫做快照模式(Snapshot)或 Token 模式,备忘录模式的用意是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在合适的时候将该对象恢复到原先 ...

  8. LeNet-5 卷积神经网络结构图

    LeNet-5是Yann LeCun在1998年设计的用于手写数字识别的卷积神经网络,当年美国大多数银行就是用它来识别支票上面的手写数字的,它是早期卷积神经网络中最有代表性的实验系统之一.可以说,Le ...

  9. Python之路【第十五篇】开发FTP多线程程序

    要求: 1.用户加密认证 2.允许同时多用户登录 3.每个用户有自己的家目录,且只能访问自己的家目录 4.对用户进行磁盘配额,每个用户的可用空间不同 5.允许用户在ftp server上随意切换目录 ...

  10. Java的访问修饰符的作用范围

    访问修饰符: private default protected public 作用范围: 访问修饰符\作用范围 所在类 同一包内其他类 其他包内子类 其他包内非子类 private 可以访问 不可以 ...