一种网络通信协议(握手阶段使用的是http 1.1),如果需要服务端主动向客户端推送信息可以使用它。
一种网络通信协议(握手阶段使用的是http 1.1),如果需要服务端主动向客户端推送信息可以使用它。
全双工,服务端和客户端可以互通消息。
相对于各种论询,不仅省掉多次握手消耗,节省带宽资源,而且不用多次去询问是否有新数据可消耗。
需要服务端配合,学习成本高些
如果需要获取新数据的频次少,一直保持链接的话,浪费服务器资源。
技术方案:nodejs + nginx + 微信小程序
hosts文件配置:
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(express());
/**
* 创建websocket服务
*/
const wss = new ws.createServer({ server, path: '/wss' }, ws => {
serveMessage(ws);
});
/**
* 监听websocket服务错误
*/
wss.on('error', (err) => {
console.log(err);
});
/**
* 进行简单的 WebSocket 服务,对于客户端发来的所有消息都回复回去
*/
function serveMessage(ws) {
// 监听客户端发来的消息
ws.on('message', (message) => {
console.log(`WebSocket received: ${message}`);
ws.send(`Server: Received(${message})`);
});
// 监听关闭事件
ws.on('close', (code, message) => {
console.log(`WebSocket client closed (code: ${code}, message: ${message || 'none'})`);
});
// 连接后马上发送成功响应
ws.send(`Server: 收到我的消息了嘛`);
}
server.listen(8888);
nginx配置(ps: 如果只是调试的话也可以使用80端口):
server {
server_name www.test.com;
listen 443;
ssl on;
ssl_certificate xxx.crt; # 证书
ssl_certificate_key yyy.key; # 密钥,生成方式可自行搜索
access_log /usr/local/etc/nginx/access.log; # 记录访问日志
error_log /usr/local/etc/nginx/error.log; # 记录错误日志
proxy_read_timeout 10s; #设置超时时间,防止node服务就是挂的
proxy_connect_timeout 5s; #设置超时时间,防止node服务就是挂的
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-Protocol "$scheme"; # 非必需
}
location / {
proxy_pass http://localhost:999;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Protocol $scheme;
}
}
小程序客户端(ps: 具体使用语法可以查看mp.weixin.qq.com官方小程序文档):
wx.connectSocket({
url: 'wss://www.test.com/wss',
data: {
message: 'test'
},
success: function (res) {
console.log('成功了', res);
},
fail: function () {
console.log('失败了');
}
});
wx.onSocketOpen(function (res) {
//balabala,可以向服务端发消息了
}
wx.onSocketMessage(function(data) {
//接收到服务端消息,balabala
}
wx.onSocketError(function (res) {
//socket错误,balabala
}
websocket 客户端自动关掉链接:原因是长时间不和websocket服务端交流,超过了nginx设置的proxy_read_timeout时间就自动关闭了,如果想长时间链接,可以采用setTimeout等类似工具判断断了重链。
upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server:...: 如果nginx确保没错,多半是websocket server的原因,比如我的,解决方法就是把node中socket.io模块换成了ws模块。