ajax轮询模拟websocket,Ajax轮询和SSE服务器推送数据与websocket模式的区别性学习
我們試想一下我們做個實時聊天的窗口有幾種方法?
在我們不刷新頁面并且可以試試更新頁面內容的方法 你這時候是不是想到了ajax沒錯確實可以
Ajax輪詢
什么是輪詢?顧名思義就是我輪著問你,規定一個時間然后我就問你 有新數據了嗎? 有新數據了嗎? 有新數據了嗎? 當有新數據的時候就更新頁面。
但是性能會很差。。。
并且這是前臺操作的 后端只需要查詢數據庫 設置好路由即可
Node后端
簡單的說就是 后端設置一個路由然后進行查詢數據獲取想要的數據的操作
const Koa = require("koa");
const static = require("koa-static");
const Router = require("koa-router");
const mysql2 = require("mysql2");
const koaBody = require("koa-body");
let app = new Koa();
app.use(static(__dirname+"/static"));
app.use(koaBody());
//連接數據庫
const connection = mysql2.createConnection({
host:"localhost",
user:"root",
password:"123",
database:"js04"
})
let router = new Router();
//訪問此路由進行獲取數據
router.get("/getData",async ctx=>{
let [rows] = await connection.promise().query("SELECT * FROM message");
ctx.body = rows;
})
app.use(router.routes());
app.listen(3000);
前端
前端我要訪問這個路由然后獲取數據 而ajax 是不會刷新頁面的。
$.ajax({
//訪問路由
url: "/getData",
success(res) {
//res 就是回的數據
console.log(res);
}
})
怎么進行輪詢呢?
上面我們說什么 規定一個時間然后 每隔多長時間進行詢問
那么這不就是定時器嗎
我們將上面的ajax進行封裝成方法里面 然后用定時器進行 輪詢訪問獲取數據
setInterval(() => {
render();
}, 500);
這樣我們是服務器資源很浪費會一直的進行訪問api進行獲取數據
我們說了 客戶端不斷的向服務端進行詢問那么有沒有 服務端主動向 客戶端進行發送消息的呢 ?
SSE (server send event) 服務器推送數據
其是基于http協議的,本質上是保持一個http長連接,客戶端向服務端發送請求,在瀏覽器與服務器建立連接之后,等有數據更新后,服務端向瀏覽器主動發送消息。這樣可以減少數量,減少服務器壓力。
而在我們服務端使用sse的時候要進行一些設置
設置頭部
"Content-type","text/event-stream"
返還數據格式
? data: 聲明數據開始
? \r\n\r\n 標志數據結尾
服務器端Node
我們設置兩個路由一個是返回首頁 第二個路由是進行一些數據的返回也就是使用sse
const http = require("http");
const fs = require("fs");
// res.write(); res.end();
let server = http.createServer((req,res)=>{
let url = req.url;
//路由返回頁面
if(url=="/"){
let data = fs.readFileSync("index.html");
res.end(data);
}else if(url=="/sse"){
res.setHeader("content-type","text/event-stream;charset=utf-8");
// 服務端端定時推送數據到客戶端;
setInterval(() => {
res.write("data:時間是"+new Date()+"\r\n\r\n");
}, 1000);
}
})
server.listen(4000);
客戶端
我們需要創建一個 EventSource對象 然后在這個對象里面有幾個事件
open:當成功建立連接時產生
message:當接收到消息時產生
error:當出現錯誤時產生
let source = new EventSource("/sse");
source.onopen = function(){
console.log("連接成功....");
console.log(source.readyState);
//這里的 readyState 會有幾種狀態
//- 0 CONNECTING (0)
//- 1 OPEN (1)
//- 2 CLOSED (2)
}
source.onmessage = function(e){
console.log("獲取到的數據是:",e.data);
document.querySelector(".exchange").innerHTML = e.data;
}
source.onerror = function(err){
return console.log(err);
}
這里的 readyState 會有幾種狀態
CONNECTING (0)
OPEN (1)
CLOSED (2)
以上的兩種方法雖然都能實現但是對性能都不是比較的友好 有沒有更好的解決方案呢?
websocket
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議
瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,并進行雙向數據傳輸。
我們后端使用的是 Node 所以我們需要借助 ws 模塊創建 websocket 實例
ws是一種易于使用,快速且經過全面測試的WebSocket客戶端和服務器實現的方法。
安裝npm install ws
簡單使用
首先我們需要導入ws并調用Server 服務端
我們進行設置端口
服務端
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 8181 });
wss.on('connection', function (ws){
console.log('client connected');
ws.on('message', function (message){
//監聽接收的數據
console.log(message);
});
// setInterval(() => {
let somedata = {
name:"張三",
age:20
}
//發送數據
ws.send(JSON.stringify(somedata));
// }, 1000);
});
客戶端
建立握手
var ws = new WebSocket("ws://localhost:8181");
打開協議
ws.onopen = function (){}
發送數據到服務端
ws.send("客戶端數據");
關閉協議:關閉協議后不能發送數據
ws.close();
接收消息
ws.onmessage = function(e){
// console.log(e.data);
}
完整點的代碼
// 握手協議;
var ws = new WebSocket("ws://localhost:8181");
ws.onopen = function(){
console.log("連接成功....");
}
ws.onmessage = function(e){
// console.log(e.data);
console.log(JSON.parse(e.data));
}
function sub(){
ws.send("發送到服務端的數據");
}
整體就是簡單的了解客戶端與服務端之間的交互問題后面會更加詳細的進行學習
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的ajax轮询模拟websocket,Ajax轮询和SSE服务器推送数据与websocket模式的区别性学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 封装svg组件
- 下一篇: RabbitMQ 延迟队列,消息延迟推送