1. 发现问题
最近在写一个基于vue3+node.js+微信小程序的项目,这个项目用到了socket,通过编码和测试,后台(基于vue)可以正常访问服务器,并且连接上socket。
但是,在微信小程序端就出问题了。使用微信小程序原生的SocketTask技术,可以正常触发connectSocket的success回调,但无法执行onSocketOpen。
let SocketTask = wx.connectSocket({
url: 'ws://localhost:4000',
header: {
'content-type': 'application/json'
},
query: {
username: "abc"
},
protocols: ['protocol1'],
method: "GET",
success: function (res) {
wx.onSocketOpen((result) => {
console.log("连接成功");
})
}
})
SocketTask.onOpen(function (res) {
console.log("已连接");
})
SocketTask.onError(function (err) {
console.log("连接失败:", err);
})
SocketTask.onClose(function (res) {
console.log('WebSocket连接已关闭!')
})
2. 解决过程
说实话,onSocketError回调的返回信息真是简单,就单单的“未完成的操作”六个字。问题到底出在哪个地方也不知道。
然后去试了weapp.socket.io,还是不行。又换了几个库,还是不行!
然后去查资料,关于这个问题的资料也是真的少,而且在论坛上大多是提问的,少有解决方法的。
而且这些解决方法对我来说也完全没用,包括修改ws协议、让服务器支持WSS的解决方案。
但有一个解答引起了我的注意,他说的是:socket的服务端版本可能与客户端版本不兼容!
3. 问题解决
这个说法让我想起了之前在socket.io官方文档上看到的版本兼容表格!
本能告诉我,困扰我两天的问题根源可能就出在这!
然后我去查微信小程序原生的SocketTask版本,没查到,去查了其他第三方库的版本,查到了但很模糊,基本没说兼容socket.io哪个版本。又去看了一下我服务端socket版本:4.7.5。
太高了,降服务器的socket版本吧?不可能,降不了一点!那就只能找适配服务端版本4.x的第三方库了。
找了半天也没找到。
然后我又去uni-app项目上测试socket,果然,通过uni-app原生的socket同样连接不了,跟小程序一样的问题。不过,倒是让我找到了适配uni-app的第三方socket库,并且这个还标注了兼容服务端4.x版本!
4. 第三方库
一款适用于uni-app的socket.io封装,可用于uni-app、微信小程序的第三方库,兼容vue2、vue3,并且最关键的是兼容socket.io@4.x的版本!!
看到这个兼容表的时候,我真是感动到眼泪都要掉出来了。
然后赶紧根据官方文档去调试。
const socket = io('http://localhost:4000', {
query: {},
transports: ['websocket', 'polling'],
timeout: 5000,
});
socket.on('connect', () => {
// ws连接已建立,此时可以进行socket.io的事件监听或者数据发送操作
// 连接建立后,本插件的功能已完成,接下来的操作参考socket.io官方客户端文档即可
console.log('ws 已连接');
// socket.io 唯一连接id,可以监控这个id实现点对点通讯
const {
id
} = socket;
socket.on(id, (message) => {
// 收到服务器推送的消息,可以跟进自身业务进行操作
console.log('ws 收到服务器消息:', message);
});
// 主动向服务器发送数据
socket.emit('send_data', {
time: +new Date(),
});
});
socket.on('error', (msg) => {
console.log('ws error', msg);
});
果然,没报错!并且提示已连接。
服务端也成功输出连接信息
5. 总结
鬼知道看到服务端输出信息时我有多兴奋。
让我百思不得其解的问题,就是出在了socket.io服务端版本与客户端版本的不兼容上。(或许是吧)
对于4.x版本的socket.io,可以通过这个:@hyoga/uni-socket.io库去解决。
低于4.x版本的,就不知道还有其他哪些库可以用了。