您當前位置>首頁 » 新聞資訊 » 小(xiǎo)程序相(xiàng)關 >
WebSocket使用(yòng)
發表時(shí)間(jiān):2021-4-30
發布人(rén):葵宇科(kē)技(jì)
浏覽次數(shù):79
是(shì)什(shén)麽
一(yī)種網絡通(tōng)信協議(yì)(握手階段使用(yòng)的→÷₩(de)是(shì)http 1.1),如(rú)果需要(yào)服務端主動向客戶端推送信息可(kě)以使用β₩∑"(yòng)它。
優勢
全雙工(gōng),服務端和(hé)客戶端可(kě)以互通(tōng)消息π↑±δ。
相(xiàng)對(duì)于各種論詢,不(bù)僅省掉多(duō)次®→握手消耗,節省帶寬資源,而且不(bù)用(yòng)多(duō)次去(qù)詢©γ問(wèn)是(shì)否有(yǒu)新數(shù)據可(kě)消耗。
存在的(de)問(wèn)題
需要(yào)服務端配合,學習(xí)成本高(gāo)©×↕↕些(xiē)
如(rú)果需要(yào)獲取新數(shù)據的(de)頻(pín)次少(shǎo),↑ 一(yī)直保持鏈接的(de)話(huà),浪費(fèi)服務器(qì)資源。
使用(yòng)方式(ps: 我使用(yòng)的(de)是(shì)本地(dì® )nginx,自(zì)己生(shēng)成的(de)證書(shū),密鑰)
技(jì)術(shù)方案:nodejs + nginx + 微£ &σ(wēi)信小(xiǎo)程序
hosts文(wén)件(jiàn)配置:
127.0.0.1 localhost
127.0.0.1 www.test.com
服務端:
var express = require('express');
var ws = require('ws');
const http = require('http');
var server = http.createServer(ex÷✔press());
/**
* 創建websocket服務
*/ ≥
const wss = new ws.createServer({ server, path: '/wss' }, ws => {
serveMessage(ws);
});
/**
* 監聽(tīng)websocket服務錯(cuò)誤
*/
wss.on('error', (err) => {
console.log(err);
});
/**
* 進行(xíng)簡單的(de) WebSocke ≠<←t 服務,對(duì)于客戶端發來(lái)的(de)所有(yǒu)消息都(dōu)回複回ελ去(qù)
*/
function serveMessage(ws) {
// 監聽(tīng)客戶端發來(lái)的(de)消息
ws.on('message', (message) => {
console.log(`WebSocket received: ${message}`);
ws.send(`Server: Received(${message})`);
});
// 監聽(tīng)關閉事(shì)件(jiàn)
ws.on('close', (code, message) => {
console.log(`WebSocket client closed (code: ${code}, message: ${message || 'none'})`);
});
// 連接後馬上(shàng)發送成功響應
ws.send(`Server: 收到(dào)我的(de)消息了(le)嘛`);
}
server.listen(8888);
nginx配置(ps: 如(rú)果隻是(shì)調試的(de)話(huà)↑☆也(yě)可(kě)以使用(yòng)80端口):
server {
server_name www.test.φ♥&com;
listen 443;
ssl on;
ssl_certificate xx<© x.crt; # 證書(shū)
ssl_certificate_key yyy.key; # 密鑰,生(shēng)成方式可(kě)自(zì)行(xíng)搜索
access_log /usr/local/etc/nginx/acce>÷>ss.log; # 記錄訪問(wèn)日(rì)志(zhì)
error_log /usr/local/etc/ngin≤ ←♦x/error.log; # 記錄錯(cuò)誤日(rì)志(zhì)
proxy_read_timeout 10s; #設置超時(shí)時(shí)間(jiān),>γ防止node服務就(jiù)是(shì)挂的(de)
proxy_conne✔↔ct_timeout 5s; #設置超時(shí)時(shí)間(jiān),防止node服務就(jiù)是(shì)挂的(de)
location /wss {
σ®≈↕
proxy_pass http://localhost:8888;
proxy_http_version 1.1; # 必需
proxy_set_header Upgrade $http_upgrade; # 必需
proxy_set_header Connection $connection_upgrade; # 必需
proxy_set_header Host $host; # 非必需
proxy_set_header X-Real-IP $remote_addr; # 非必需
proxy_set_header X-Real-Port $remote_port; # 非必需
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 非必需
proxy_set_header X-Forwarded-P×₹rotocol "$scheme"; # 非必需
}
location / {
proxy_pass http://localhost:999₽♠;
proxy_set_header Host $host;
proxy_set_header X-R☆'×eal-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-₩≠>★Protocol $scheme;
}
}
小(xiǎo)程序客戶端(ps: 具體(tǐ)使用(yòng)語法可(kě)以查看✔←♥(kàn)mp.weixin.qq.com官方小(xi'¶≠₽ǎo)程序文(wén)檔):
wx.connectSocket({
url: 'wss://www.test.com/wss',
data: {
message: 'test'
},
success: function (res) {
console.log('成功了(le)', res);
},
fail: function () {
console.log('失敗了(le)');
}
});
wx.onSocketOpen(function (res) {
//balabala,可(kě)以向服務端發消息了(le)
}
wx.onSocketMessage(function(data) {
//接收到(dào)服務端消息,balabala
}
wx.onSocketError(function (res) {
//socket錯(cuò)誤,balabala
}
遇到(dào)的(de)問(wèn)題
websocket 客戶端自(zì)動關掉鏈接:原因是(shì)長(c>háng)時(shí)間(jiān)不(bù)和(hé)websocket服務端交流,超過了(®π₹±le)nginx設置的(de)proxy_read_timeout時(shí)間(•>λjiān)就(jiù)自(zì)動關閉了(le),如(rú)果想長(cháng)時(↔₹shí)間(jiān)鏈接,可(kě)以采用(yòng)setTimeout等'>類似工(gōng)具判斷斷了(le)重鏈。
upstream prematurely closed connecti εon while reading response hea♣$¶der from upstream, client: 127.0.0.1,☆↑♠ server:...: 如(rú)果nginx确保沒錯(cuò),多(duō)半≤↑是(shì)websocket server的(de)原因,比如(rú)我的(de),解決方法β≈¥©就(jiù)是(shì)把node中socket.io模塊換成了(★♠le)ws模塊。