消息服务器 推送技术,SSE服务器推送技术

SSE即 server send event 服务器发送事件,在在早期可能会使用ajax向服务器轮询的方式,使浏览器第一时间接受到服务器的消息,但这种频率不好控制,消耗也比较大。

但是对于SSE来说,当客户端向服务端发送请求,服务端会抓住这个请求不放,等到有数据时才返回给客户端,但客户端手动消息后,再向服务器发送请求,周而复始。这种方式好处是减少了服务器的请求数量,也大大减少了服务器的压力。

以下是第一种方式的代码的演示,浏览器不断向服务器请求,服务器用线程睡眠5s再返回结果。

1、SseController 控制器

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Random;

/**

* @description: 服务器端推送控制器

*

* @author: Shenshuaihu

* @version: 1.0

* @data: 2019-06-25 23:29

*/

@Controller

public class SseController {

/**

* 输出类型 text/event-stream 是对服务器端SSE的支持

* 此处每5s向浏览器推送随机消息

* @return

*/

@RequestMapping(value = "/push", produces = "text/event-stream")

public @ResponseBody String push() {

Random random = new Random();

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

return "data:Testing 1,2,3: " + random.nextInt() + "\n\n";

}

}

2、显示结果的页面 sse.jsp

SSE-Code

sse.jsp

服务器推送 可以用于消息订阅

解决长短轮询不是解决问题

server send event 当客户端方服务器发送请求时 服务器抓住不放 等有数据时 再回复给客户端,客户端收到消息时发给送给服务器,如此循环

参考内容:

https://www.jianshu.com/p/bc5a9b4a1cd1

console.log("!!Window EventSource: " + !!Window.EventSource)

if (!!window.EventSource) {

var source = new EventSource('push');

s = '';

source.addEventListener('message', function (evt) {

s += evt.data + "
";

$("#msgFromPush").html(s);

});

source.addEventListener('open', function (evt) {

console.log("连接打开.")

})

// 添加SSE客户端监听,获取服务端推送的消息

source.addEventListener('error', function (evt) {

if (evt.readyState == EventSource.CLOSED) {

console.log("连接关闭.")

} else {

console.log(evt.readyState)

}

}, false);

} else {

console.log("你的浏览器不支持SSE.")

}

/*if(window.EventSource){

var eventSource = new EventSource("http://localhost:8080/push");

//只要和服务器连接,就会触发open事件

eventSource.addEventListener("open",function(){

console.log("和服务器建立连接");

});

//处理服务器响应报文中的load事件

eventSource.addEventListener("load",function(e){

console.log("服务器发送给客户端的数据为:" + e.data);

});

//如果服务器响应报文中没有指明事件,默认触发message事件

eventSource.addEventListener("message",function(e){

console.log("服务器发送给客户端的数据为:" + e.data);

});

//发生错误,则会触发error事件

eventSource.addEventListener("error",function(e){

console.log("服务器发送给客户端的数据为:" + e.data);

});

}

else{

console.log("服务器不支持EvenSource对象");

}*/

显示的结果

b73d5faea350

SSE-.png

二、使用Servlet 3.0 + 异步方法处理,第二种方式演示,浏览器循环请求服务端,服务端用定时任务,每5S设置一下数据,返回给浏览器

1、开启异步方法的支持 WebInitializer.java

import org.springframework.web.WebApplicationInitializer;

import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletRegistration.Dynamic;

/**

* @description: Web配置 代替web.xml

* @author: Shenshuaihu

* @version: 1.0

* @data: 2019-06-13 23:22

*/

public class WebInitializer implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();

context.register(MyMvcConfig.class);

// 新建的webApplicationContext ,注册配置类,并将其和当前servletContext关联。

context.setServletContext(servletContext);

// 注册SpringMVC 的 DispatcherServlet

Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));

servlet.addMapping("/");

servlet.setLoadOnStartup(1);

// 开启对异步的支持

servlet.setAsyncSupported(true);

}

}

2、AsyncController.java 控制层,只用掉service

import com.ch4.service.PushService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.context.request.async.DeferredResult;

/**

* @description:

*

* @author: Shenshuaihu

* @version: 1.0

* @data: 2019-06-27 08:32

*/

@Controller

public class AsyncController {

@Autowired

private PushService pushService;

@RequestMapping("/defer")

@ResponseBody

public DeferredResult deferredCall() {

return pushService.getAsyncUpdate();

}

}

3、PushService.java

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Service;

import org.springframework.web.context.request.async.DeferredResult;

/**

* @description: SSE 定时任务

* 在PushService里面产生 DeferredResult 给控制器使用,

* 通过 @Scheduled 定时更新DeferredResult

*

* @author: Shenshuaihu

* @version: 1.0

* @data: 2019-06-27 08:32

*/

@Service

public class PushService {

private DeferredResult deferredResult;

public DeferredResult getAsyncUpdate() {

deferredResult = new DeferredResult();

return deferredResult;

}

@Scheduled(fixedDelay = 5000)

public void refresh() {

if (deferredResult != null) {

deferredResult.setResult(new Long(System.currentTimeMillis()).toString());

}

}

}

3、数据页面async.jsp

pageEncoding="UTF-8"%>

async support-Code

defer.jsp

deferred();

function deferred() {

$.get('defer', function (data) {

console.log(data);

s = '';

s += data + "
";

$('#defer').html(s)

// 完成后在向服务器请求

deferred();

}

);

}

4、需要在核销配置类用开启任务

@Configuration

@EnableWebMvc

@ComponentScan("com.ch4")

@EnableScheduling

public class MyMvcConfig extends WebMvcConfigurerAdapter {}

b73d5faea350

SSE-aync.png

总结:

SSE用于订阅消息,是需要浏览器不断的请求,与websocket有相似之处

2019/06/30晚于成都

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Contest2162 - 2019-3-28 高一noip基础知识点 测试5 题解版

传送门 T1 单调栈 按照b排序 在家每一个物品时,判断一下a和b的关系 如果s[sta[top]].a>s[i].b,就弹栈 记录所有时候的height,并取最大值 T2 单调栈裸题 单调栈是干什么的?? 单调栈是记录一个数的一侧的第一个比他大…

在package.json里面的script设置环境变量,区分开发及生产环境。注意mac与windows的设置方式不一样...

在package.json里面的script设置环境变量,区分开发及生产环境。 注意mac与windows的设置方式不一样。 "scripts": {"publish-mac": "export NODE_ENVprod&&webpack -p --progress --colors","publish-win": "…

leetcode 978. 最长湍流子数组(动态规划)

978. 最长湍流子数组 当 A 的子数组 A[i], A[i1], …, A[j] 满足下列条件时&#xff0c;我们称其为湍流子数组&#xff1a; 若 i < k < j&#xff0c;当 k 为奇数时&#xff0c; A[k] > A[k1]&#xff0c;且当 k 为偶数时&#xff0c;A[k] < A[k1]&#xff1b; 或 …

人工智能取代工作_人工智能正在取代人们的工作-开发人员是下一个吗?

人工智能取代工作I was recently asked to comment on whether there was any point in becoming a developer right now, because AI might be doing your job very soon.最近有人要求我评论一下现在成为开发人员是否有任何意义&#xff0c;因为AI可能很快就会完成您的工作。 …

python类self_Python类中的self到底是干啥的

Python编写类的时候&#xff0c;每个函数参数第一个参数都是self&#xff0c;一开始我不管它到底是干嘛的&#xff0c;只知道必须要写上。后来对Python渐渐熟悉了一点&#xff0c;再回头看self的概念&#xff0c;似乎有点弄明白了。首先明确的是self只有在类的方法中才会有&…

PHP中关于取模运算及符号

执行程序段<?php echo 8%(-2) ?>&#xff0c;输出结果是&#xff1a; %为取模运算&#xff0c;以上程序将输出0 $a%$b,其结果的正负取决于$a的符号。 echo ((-8)%3); //将输出-2 echo (8%(-3)); //将输出2转载于:https://www.cnblogs.com/457248499-qq-com/p…

[pytorch] Pytorch入门

Pytorch入门 简单容易上手&#xff0c;感觉比keras好理解多了&#xff0c;和mxnet很像&#xff08;似乎mxnet有点借鉴pytorch&#xff09;&#xff0c;记一记。 直接从例子开始学&#xff0c;基础知识咱已经看了很多论文了。。。 import torch import torch.nn as nn import to…

无线服务器密码让别人改了,wifi密码被改了怎么办_wifi密码被别人改了怎么办?-192路由网...

wifi密码被别人改了怎么办&#xff1f;wifi密码之所以被别人修改&#xff0c;是因为其他人知道了你路由器的登录密码。所以&#xff0c;如果发现自己wifi密码被别人修改了&#xff0c;应该立刻登录到路由器设置界面&#xff0c;修改路由器登录密码、修改wifi密码、并调整wifi加…

[archlinux][hardware] 查看SSD的使用寿命

因为最近把16GB的SSD做成了HDD的cache&#xff0c;所以比较关系寿命问题。 使用smartctl工具。 参考&#xff1a;https://www.v2ex.com/t/261373 linux 下面只有 smartmontools 这一个工具&#xff0c;而且只对像三丧和 intel 这样的大厂支持良好&#xff0c;其余的厂家文档不全…

leetcode174. 地下城游戏(动态规划)

一些恶魔抓住了公主&#xff08;P&#xff09;并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士&#xff08;K&#xff09;最初被安置在左上角的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正…

如何设置Windows版Go —快速简便的指南

by Linda Gregier琳达格雷格(Linda Gregier) Another great language to add to your full-stack developer tool belt is the simple and productive general-purpose programming language of Go.添加到您的全栈开发人员工具带中的另一种很棒的语言是Go的简单而高效的通用编…

python计算现场得分_浅谈用 Python 计算文本 BLEU 分数

浅谈用 Python 计算文本 BLEU 分数BLEU, 全称为 Bilingual Evaluation Understudy(双语评估替换), 是一个比较候选文本翻译与其他一个或多个参考翻译的评价分数尽管 BLEU 一开始是为翻译工作而开发, 但它也可以被用于评估文本的质量, 这种文本是为一套自然语言处理任务而生成的…

Unity的几个特殊文件夹

1.以.开头的文件夹会被unity忽略&#xff0c;资源不会被导入&#xff0c;脚本不会编译。 2.Standard Assets和Pro Standard Assets&#xff1a;在这个文件夹中的脚本最先被编译。 3.Editor&#xff1a;以Editor命名的文件夹允许其中的脚本访问Unity Editor的API。如果脚本中使用…

怎么上传文件到kk服务器,VS Code 关于SFTP上传文件到多服务器的配置

工欲善其事&#xff0c;必先利其器&#xff01;刚学前端的时候一直用的DW来编写代码&#xff0c;其功能非常强大&#xff0c;但在Linux下不能用&#xff0c;所以就转VS Code了。但是刚开始使用VS Code的时候&#xff0c;很多DW上的功能需要自己安装扩展&#xff0c;并配置才可以…

CentOS7 Firewall NAT 及端口映射

本节介绍用CentOS7的Firewalll来做NAT以及端口映射实验拓扑:因为我的环境里CentOS7上有KVM虚拟机需要共享网卡上网&#xff0c;所以我把网卡都添加到了桥里面&#xff0c;当然这里也可以不用桥&#xff0c;直接用物理网口&#xff1b;用nmcli创建桥&#xff0c;并添加网口到桥&…

JVM源码---教你傻瓜式编译openjdk7(JAVA虚拟机爱好者必看)

LZ经过一个星期断断续续的研究&#xff0c;终于成功的搞定了JDK的成功编译与调试。尽管网络上的教程也有不少&#xff0c;包括源码中也有自带的编译步骤说明&#xff0c;但真正自己动手的话&#xff0c;还是会遇到不少意料之外的错误。 为了方便各位猿友编译&#xff0c;LZ临时…

leetcode1105. 填充书架(动态规划)

附近的家居城促销&#xff0c;你买回了一直心仪的可调节书架&#xff0c;打算把自己的书都整理到新的书架上。 你把要摆放的书 books 都整理好&#xff0c;叠成一摞&#xff1a;从上往下&#xff0c;第 i 本书的厚度为 books[i][0]&#xff0c;高度为 books[i][1]。 按顺序 将…

python 微信bot_使用Tweepy在Python中创建Twitter Bot

python 微信botby Lucas Kohorst卢卡斯科斯特(Lucas Kohorst) 使用Tweepy在Python中创建Twitter Bot (Create a Twitter Bot in Python Using Tweepy) With about 15% of Twitter being composed of bots, I wanted to try my hand at it. I googled how to create a Twitter …

第五周学习进度

1.学习所花时间&#xff1a;单纯Java是12个小时左右&#xff1b; 2.代码量&#xff1a;大约300行&#xff1b; 3.博客量&#xff1a;1篇。 4.了解到的知识点&#xff1a;数据库语言的增删改查 5.下周计划除了掌握课上知识外&#xff0c;还要再复习之前的关于Java的相关知识点。…

另一个域的cookie_一定要知道的第一方Cookie和第三方Cookie

Cookie 是您访问过的网站创建的文件&#xff0c;用于存储浏览信息&#xff0c;例如您的网站偏好设置或个人资料信息。共有两种类型的 Cookie&#xff1a;第一方 Cookie 是由地址栏中列出的网站域设置的 Cookie&#xff0c;而第三方 Cookie 来自在网页上嵌入广告或图片等项的其他…