记socket.io实现websocket长连接
工程中需要使用websocket实现后端和前端之间的实时信息传输,后端需要将数据实时推送到前端并展示。
工程整体框架为前后端分离,其中后端服务使用node.js 实现,前端采用Vue 框架实现。
基本配置
服务端配置
由于工程前后端分离,所以需要解决跨域问题,在选项中添加 cors:{origin: "*",credentials:true}
整体配置如下: websocket 和 http 服务监听相同的端口。
也可以参考官网 document 初始化 websocket server
var io = require('socket.io')(8082,{cors:{
origin: "*",credentials:true}
});
客户端配置
引用 socket.io-client 包
前后端在同一域时,不用添加路径
const { io } = require("socket.io-client");
const socket = io();
来自不同域时,需要添加路径URL,并在服务端配置跨域
const socket = io("https://server-domain.com");
也可以参考官网 document
监听和发送事件 on 和 emit
io.sockets.on('connection', function(socket) {
var ip = socket.handshake.headers['x-forwarded-for'] || socket.conn.remoteAddress.split(":")[3];
console.log("socket connected: ", ip);
const count = io.engine.clientsCount;
console.log("client count:" , count);
socket.emit('ping','socket connected');
socket.on('disconnect', function(socket) {
console.log('disconnected: ',ip)
});
socket.on('ping', (msg)=>{
console.log(msg);
});
});
遇到的问题
1. 路径设置问题
socket.io 如果没有在options 选项中指定 websocket建立连接进行handshake 的路径,则默认为 “/socket.io”
客户端进行连接时 URL只需要写 IP+port
或者 域名
就可以了
2. 使用Nginx 转发 websocket 连接, 并使用 wss 协议
nginx.conf 配置:
server {
listen 443 ssl;
server_name【your_servername】;
ssl_certificate [path_to_cert];
ssl_certificate_key [path_to_key];
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ----;
ssl_prefer_server_ciphers on;
location ~^/(socket.io/) {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection keep-alive;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:8082;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
其中 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
三个配置比较重要