很奇怪 wx.sendSocketMessage 在电脑版微信中,发送消息会报错?
我发送的内容明明是 buffer 格式,发送的内容也没什么特别的。但是在电脑版的微信中 wx.onSocketError 却会报错:
createSocketTask: Browser sent a text frame containing invalid UTF-8
在开发工具,真机,平板均能正常收发消息,就PC版微信有问题。
可将下面代码直接复制到新建的项目中运行。
const app = getApp()
Page({
data: {},
onLoad: function () {
var url = "wss://pml.dian3x.com";
wx.connectSocket({ url: url });
wx.onSocketOpen(function (res) {
console.log("# open: " + url);
// 这里发送握手包,服务端能正常收发
var packet = Package.encode(Package.TYPE_HANDSHAKE, String.toUTF8Array(JSON.stringify(handshakeBuffer)));
sendSocketMessage(packet.buffer);
// 这里稍微延迟,等上面握手包发送完成后,握手成功后,下面发送的消息,服务端才会接收消息。
setTimeout(function () {
var route = "connector.StoryConfigHandler.getConfigInfo";
var msg = {
appGuid: "ef67dfc4-dec8-4ad2-9941-2861933615dc",
sessionId: "e9cc5ddd-6a79-0e9f-7abd-4a8265b198da",
version: "1.7.0"
};
// 在电脑版微信中,虽然下面 wx.sendSocketMessage 执行了 success 回调,但事实上服务端并没有收到任何内容。
// 并且 wx.onSocketError 报错: createSocketTask: Browser sent a text frame containing invalid UTF-8
// 这些代码是从项目中抽取整理出来的,在开发工具,真机,平板均能正常收发消息,就PC版微信有问题。
sendMessage(route, msg);
}, 2000);
});
wx.onSocketError(function (res) {
console.error("---- wx.onSocketError ----");
console.error(res);
});
wx.onSocketClose(function (res) {
console.log("---- wx.onSocketClose ----");
console.log(res);
});
wx.onSocketMessage(function (res) {
console.log("---- wx.onSocketMessage ----");
console.log(res);
});
},
});
// unicode string to utf8 byte
if (!String.toUTF8Array) {
String.toUTF8Array = function (str) {
var utf8 = [];
for (var i = 0; i < str.length; i++) {
var charcode = str.charCodeAt(i);
if (charcode < 0x80) utf8.push(charcode);
else if (charcode < 0x800) {
utf8.push(0xc0 | (charcode >> 6),
0x80 | (charcode & 0x3f));
}
else if (charcode < 0xd800 || charcode >= 0xe000) {
utf8.push(0xe0 | (charcode >> 12),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
}
// surrogate pair
else {
i++;
// UTF-16 encodes 0x10000-0x10FFFF by
// subtracting 0x10000 and splitting the
// 20 bits of 0x0-0xFFFFF into two halves
charcode = 0x10000 + (((charcode & 0x3ff) << 10)
| (str.charCodeAt(i) & 0x3ff))
utf8.push(0xf0 | (charcode >> 18),
0x80 | ((charcode >> 12) & 0x3f),
0x80 | ((charcode >> 6) & 0x3f),
0x80 | (charcode & 0x3f));
}
}
return utf8;
};
}
//
var JS_WS_CLIENT_TYPE = 'js-websocket';
var JS_WS_CLIENT_VERSION = '0.0.1';
var handshakeBuffer = {
'sys': {
type: JS_WS_CLIENT_TYPE,
version: JS_WS_CLIENT_VERSION
},
'user': {
}
};
//
var Package = {};
Package.TYPE_HANDSHAKE = 1;
Package.TYPE_DATA = 4;
var PKG_HEAD_BYTES = 4;
var MSG_FLAG_BYTES = 1;
var MSG_ROUTE_LEN_BYTES = 1;
var MSG_ROUTE_CODE_MAX = 0xffff;
var ByteArray = Uint8Array; // Buffer
Package.encode = function (type, body) {
var length = body ? body.length : 0;
var buffer = new ByteArray(PKG_HEAD_BYTES + length);
var index = 0;
buffer[index++] = type & 0xff;
buffer[index++] = (length >> 16) & 0xff;
buffer[index++] = (length >> 8) & 0xff;
buffer[index++] = length & 0xff;
if (body) {
copyArray(buffer, index, body, 0, length);
}
return buffer;
};
var copyArray = function (dest, doffset, src, soffset, length) {
if ('function' === typeof src.copy) {
// Buffer
src.copy(dest, doffset, soffset, soffset + length);
} else {
// Uint8Array
for (var index = 0; index < length; index++) {
dest[doffset++] = src[soffset++];
}
}
};
var caculateMsgIdBytes = function (id) {
var len = 0;
do {
len += 1;
id >>= 7;
} while (id > 0);
return len;
};
var encodeMsgFlag = function (type, compressRoute, buffer, offset) {
buffer[offset] = (type << 1) | 0;
return offset + MSG_FLAG_BYTES;
};
var encodeMsgId = function (id, idBytes, buffer, offset) {
var index = offset + idBytes - 1;
buffer[index--] = id & 0x7f;
while (index >= offset) {
id >>= 7;
buffer[index--] = id & 0x7f | 0x80;
}
return offset + idBytes;
};
var encodeMsgRoute = function (compressRoute, route, buffer, offset) {
if (compressRoute) {
if (route > MSG_ROUTE_CODE_MAX) {
throw new Error('route number is overflow');
}
buffer[offset++] = (route >> 8) & 0xff;
buffer[offset++] = route & 0xff;
} else {
if (route) {
buffer[offset++] = route.length & 0xff;
copyArray(buffer, offset, route, 0, route.length);
offset += route.length;
} else {
buffer[offset++] = 0;
}
}
return offset;
};
var encodeMsgBody = function (msg, buffer, offset) {
copyArray(buffer, offset, msg, 0, msg.length);
return offset + msg.length;
};
var Message = {};
Message.encode = function (id, type, compressRoute, route, msg) {
// caculate message max length
var idBytes = caculateMsgIdBytes(id);
var msgLen = MSG_FLAG_BYTES + idBytes;
msgLen += MSG_ROUTE_LEN_BYTES;
if (route) {
route = String.toUTF8Array(route);
if (route.length > 255) {
throw new Error('route maxlength is overflow');
}
msgLen += route.length;
}
if (msg) {
msgLen += msg.length;
}
var buffer = new ByteArray(msgLen);
var offset = 0;
// add flag
offset = encodeMsgFlag(type, compressRoute, buffer, offset);
// add message id
offset = encodeMsgId(id, idBytes, buffer, offset);
// add route
offset = encodeMsgRoute(compressRoute, route, buffer, offset);
// add body
offset = encodeMsgBody(msg, buffer, offset);
return buffer;
};
var sendMessage = function (route, msg) {
console.log("# " + route);
console.log(msg);
msg = String.toUTF8Array(JSON.stringify(msg));
msg = Message.encode(1, 0, 0, route, msg);
var packet = Package.encode(Package.TYPE_DATA, msg);
// console.log(packet);
sendSocketMessage(packet.buffer);
};
var sendSocketMessage = function (buffer) {
wx.sendSocketMessage({
data: buffer,
success: function (res) { console.log("---- wx.sendSocketMessage successed ----"); },
fail: function (res) {
console.log("---- wx.sendSocketMessage failed ----");
console.log(res);
}
});
};
1 回复