消息服務器 推送技術,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.pswp.cn/news/394494.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/394494.shtml
英文地址,請注明出處:http://en.pswp.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 來自在網頁上嵌入廣告或圖片等項的其他…