日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ajax轮询模拟websocket,Ajax轮询和SSE服务器推送数据与websocket模式的区别性学习

發(fā)布時(shí)間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ajax轮询模拟websocket,Ajax轮询和SSE服务器推送数据与websocket模式的区别性学习 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們?cè)囅胍幌挛覀冏鰝€(gè)實(shí)時(shí)聊天的窗口有幾種方法?

在我們不刷新頁(yè)面并且可以試試更新頁(yè)面內(nèi)容的方法 你這時(shí)候是不是想到了ajax沒(méi)錯(cuò)確實(shí)可以

Ajax輪詢

什么是輪詢?顧名思義就是我輪著問(wèn)你,規(guī)定一個(gè)時(shí)間然后我就問(wèn)你 有新數(shù)據(jù)了嗎? 有新數(shù)據(jù)了嗎? 有新數(shù)據(jù)了嗎? 當(dāng)有新數(shù)據(jù)的時(shí)候就更新頁(yè)面。

但是性能會(huì)很差。。。

并且這是前臺(tái)操作的 后端只需要查詢數(shù)據(jù)庫(kù) 設(shè)置好路由即可

Node后端

簡(jiǎn)單的說(shuō)就是 后端設(shè)置一個(gè)路由然后進(jìn)行查詢數(shù)據(jù)獲取想要的數(shù)據(jù)的操作

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());

//連接數(shù)據(jù)庫(kù)

const connection = mysql2.createConnection({

host:"localhost",

user:"root",

password:"123",

database:"js04"

})

let router = new Router();

//訪問(wèn)此路由進(jìn)行獲取數(shù)據(jù)

router.get("/getData",async ctx=>{

let [rows] = await connection.promise().query("SELECT * FROM message");

ctx.body = rows;

})

app.use(router.routes());

app.listen(3000);

前端

前端我要訪問(wèn)這個(gè)路由然后獲取數(shù)據(jù) 而ajax 是不會(huì)刷新頁(yè)面的。

$.ajax({

//訪問(wèn)路由

url: "/getData",

success(res) {

//res 就是回的數(shù)據(jù)

console.log(res);

}

})

怎么進(jìn)行輪詢呢?

上面我們說(shuō)什么 規(guī)定一個(gè)時(shí)間然后 每隔多長(zhǎng)時(shí)間進(jìn)行詢問(wèn)

那么這不就是定時(shí)器嗎

我們將上面的ajax進(jìn)行封裝成方法里面 然后用定時(shí)器進(jìn)行 輪詢?cè)L問(wèn)獲取數(shù)據(jù)

setInterval(() => {

render();

}, 500);

這樣我們是服務(wù)器資源很浪費(fèi)會(huì)一直的進(jìn)行訪問(wèn)api進(jìn)行獲取數(shù)據(jù)

我們說(shuō)了 客戶端不斷的向服務(wù)端進(jìn)行詢問(wèn)那么有沒(méi)有 服務(wù)端主動(dòng)向 客戶端進(jìn)行發(fā)送消息的呢 ?

SSE (server send event) 服務(wù)器推送數(shù)據(jù)

其是基于http協(xié)議的,本質(zhì)上是保持一個(gè)http長(zhǎng)連接,客戶端向服務(wù)端發(fā)送請(qǐng)求,在瀏覽器與服務(wù)器建立連接之后,等有數(shù)據(jù)更新后,服務(wù)端向?yàn)g覽器主動(dòng)發(fā)送消息。這樣可以減少數(shù)量,減少服務(wù)器壓力。

而在我們服務(wù)端使用sse的時(shí)候要進(jìn)行一些設(shè)置

設(shè)置頭部

"Content-type","text/event-stream"

返還數(shù)據(jù)格式

? data: 聲明數(shù)據(jù)開(kāi)始

? \r\n\r\n 標(biāo)志數(shù)據(jù)結(jié)尾

服務(wù)器端Node

我們?cè)O(shè)置兩個(gè)路由一個(gè)是返回首頁(yè) 第二個(gè)路由是進(jìn)行一些數(shù)據(jù)的返回也就是使用sse

const http = require("http");

const fs = require("fs");

// res.write(); res.end();

let server = http.createServer((req,res)=>{

let url = req.url;

//路由返回頁(yè)面

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");

// 服務(wù)端端定時(shí)推送數(shù)據(jù)到客戶端;

setInterval(() => {

res.write("data:時(shí)間是"+new Date()+"\r\n\r\n");

}, 1000);

}

})

server.listen(4000);

客戶端

我們需要?jiǎng)?chuàng)建一個(gè) EventSource對(duì)象 然后在這個(gè)對(duì)象里面有幾個(gè)事件

open:當(dāng)成功建立連接時(shí)產(chǎn)生

message:當(dāng)接收到消息時(shí)產(chǎn)生

error:當(dāng)出現(xiàn)錯(cuò)誤時(shí)產(chǎn)生

let source = new EventSource("/sse");

source.onopen = function(){

console.log("連接成功....");

console.log(source.readyState);

//這里的 readyState 會(huì)有幾種狀態(tài)

//- 0 CONNECTING (0)

//- 1 OPEN (1)

//- 2 CLOSED (2)

}

source.onmessage = function(e){

console.log("獲取到的數(shù)據(jù)是:",e.data);

document.querySelector(".exchange").innerHTML = e.data;

}

source.onerror = function(err){

return console.log(err);

}

這里的 readyState 會(huì)有幾種狀態(tài)

CONNECTING (0)

OPEN (1)

CLOSED (2)

以上的兩種方法雖然都能實(shí)現(xiàn)但是對(duì)性能都不是比較的友好 有沒(méi)有更好的解決方案呢?

websocket

WebSocket 是 HTML5 開(kāi)始提供的一種在單個(gè) TCP 連接上進(jìn)行全雙工通訊的協(xié)議

瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。

我們后端使用的是 Node 所以我們需要借助 ws 模塊創(chuàng)建 websocket 實(shí)例

ws是一種易于使用,快速且經(jīng)過(guò)全面測(cè)試的WebSocket客戶端和服務(wù)器實(shí)現(xiàn)的方法。

安裝npm install ws

簡(jiǎn)單使用

首先我們需要導(dǎo)入ws并調(diào)用Server 服務(wù)端

我們進(jìn)行設(shè)置端口

服務(wù)端

var WebSocketServer = require('ws').Server,

wss = new WebSocketServer({ port: 8181 });

wss.on('connection', function (ws){

console.log('client connected');

ws.on('message', function (message){

//監(jiān)聽(tīng)接收的數(shù)據(jù)

console.log(message);

});

// setInterval(() => {

let somedata = {

name:"張三",

age:20

}

//發(fā)送數(shù)據(jù)

ws.send(JSON.stringify(somedata));

// }, 1000);

});

客戶端

建立握手

var ws = new WebSocket("ws://localhost:8181");

打開(kāi)協(xié)議

ws.onopen = function (){}

發(fā)送數(shù)據(jù)到服務(wù)端

ws.send("客戶端數(shù)據(jù)");

關(guān)閉協(xié)議:關(guān)閉協(xié)議后不能發(fā)送數(shù)據(jù)

ws.close();

接收消息

ws.onmessage = function(e){

// console.log(e.data);

}

完整點(diǎn)的代碼

// 握手協(xié)議;

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("發(fā)送到服務(wù)端的數(shù)據(jù)");

}

整體就是簡(jiǎn)單的了解客戶端與服務(wù)端之間的交互問(wèn)題后面會(huì)更加詳細(xì)的進(jìn)行學(xué)習(xí)

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的ajax轮询模拟websocket,Ajax轮询和SSE服务器推送数据与websocket模式的区别性学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。