服务端:Egg
客户端:小程序
推荐使用weapp.socket.io
// weapp.socket.io项目打包后的文件
const io = require('../static/js/weapp.socket.io');
io(url, {
transports: ['websocket'], // 此项必须设置
});
namespace的键需要和路由配置中io.of后面保持一致
config.io = {
// namespace命名空间配置为
namespace: {
'/api': {
// 预处理器中间件, 我们这里配置了一个auth, 进行权限判断, 它对应的文件是/app/io/middleware/auth.js, 这里可以配置多个文件, 用逗号隔开
connectionMiddleware: [ 'auth' ], // 这里我们可以做一些权限校验之类的操作
packetMiddleware: [], // 通常用于对消息做预处理,又或者是对加密消息的解密等操作
},
},
};
io.of('/api').route('connect', io.controller.home.connect);
namespace的键需要与客户端建立连接的url的路径部分一样(端口后面,不包含查询)
config.io = {
// namespace命名空间配置为
namespace: {
'/api': {
// 预处理器中间件, 我们这里配置了一个auth, 进行权限判断, 它对应的文件是/app/io/middleware/auth.js, 这里可以配置多个文件, 用逗号隔开
connectionMiddleware: [ 'auth' ], // 这里我们可以做一些权限校验之类的操作
packetMiddleware: [], // 通常用于对消息做预处理,又或者是对加密消息的解密等操作
},
},
};
const io = require('../static/js/weapp.socket.io');
io('http://localhost:8080/api', {
transports: ['websocket'], // 此项必须设置
});
io.of('/api').route('connect', io.controller.home.connect);
io.of('/api').route('updatelist', io.controller.home.updatelist);
io('http://localhost:8080/api', {
transports: ['websocket'], // 此项必须设置
});
http://localhost:8080/socket.io
,io会自动截取url并修改/api
,需要服务端config的io中namespace配置,并且路由中io.of参数保持一致特殊情况
当egg服务端被Nginx代理出带有路径时,需要特殊处理,例如:请求路径需要变成http://localhost:8080/dev/socket.io
Nginx
location ^~/dev/socket.io {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:8080/socket.io;
}
sockte.io客户端
io('http://localhost:8080/api', {
path: '/dev/socket.io',
transports: ['websocket'], // 此项必须设置
});
上面的io第一参数url一定不要写成http://localhost:8080/dev/api
,写成这样会造成服务端的namespace不匹配,看ws消息可以知道会变成/dev/api
,之前是/api
io('http://localhost:8080/api', {
path: '/dev/socket.io',
transports: ['websocket'], // 此项必须设置
extraHeaders: {
token: wx.getStorageSync(TOKEN), // header增加了token
},
reconnectionAttempts: 3, // 失败后重新连接次数,一直失败总共尝试四次
reconnectionDelay: 2000, // 重新连接间隔时间毫秒
});
小程序请求过来的请求头直接透传给接口,由于小程序请求egg是websocket所以有握手环节的协议升级
Connection: Upgrade
Upgrade: websocket
但是接口不支持websocket协议,因此握手环节就失败,更不会返回结果,处理是把这两个请求头去掉。
socket.io默认只会建立一个连接,前一个执行的很可能不会触发(监听)收消息回调。此时需要配置forceNew: true
io('http://localhost:8080/api', {
path: '/dev/socket.io',
transports: ['websocket'], // 此项必须设置
extraHeaders: {
token: wx.getStorageSync(TOKEN), // header增加了token
},
reconnectionAttempts: 3, // 失败后重新连接次数,一直失败总共尝试四次
reconnectionDelay: 2000, // 重新连接间隔时间毫秒
forceNew: true,
});
开发工具模拟器、真机调试、断开真机之后打开调试都可以连接websocket,原因是没有配置socket安全域名。小程序遇到未知报错可以使用下面代码查看
wx.onError(err => {
wx.showModal({
title: 'err',
content: err
})
})