我正在从我的网页连接到Web套接字服务器,并通过它向服务器发送点击事件。
在我的点击例行程序中,我正在做
if (socket.readyState === WebSocket.OPEN) {
//send
}else {
msgsArray.push(messages)
}
然后在socket.onOpen中,我使用shift()发布来自msgsArray的所有消息;
但是似乎有一种可能的竞争条件,如果在我检查Web套接字未打开之后但在将消息添加到数组之前打开了套接字。
由于JavaScript是单线程的,实际上没有竞争条件吗?如果没有,我有什么办法可以使此“线程”安全?是否保证只有在我的点击事件处理完成后才会调用onOpen?
-更新---
我所指的竞争条件是我正在检查的地方socket.readyState不是OPEN,但是它变成OPEN并且在我将消息添加到数组之前调用socket.onopen。但是实际上我不认为这会发生,是吗?在点击例程完成之前无法调用onopen,对吗?但是相反的情况是:socket.readyState是OPEN,但是在我写的时候就关闭了?我将在其周围添加try catch
并将其添加到catch块中的数组。我认为这应该处理所有可能的情况。如果没有,您可以建议吗?
阅读完WebSocket.send的文档后,我将代码更新为完全“种族安全”
//Obj.socketMessagesToSend is a JS array ([])
if (Obj.socket && Obj.socket.readyState === WebSocket.OPEN) {
try {
Obj.socket.send(JSON.stringify(report));
} catch (e) {
Obj.socketMessagesToSend.push(JSON.stringify(report));
Obj.connectToWebSocket();
}
} else {
Obj.socketMessagesToSend.push(JSON.stringify(report));
Obj.connectToWebSocket();
}
和
Obj.connectToWebSocket() = function() {
if (Obj.socket && (Obj.socket.readyState === WebSocket.CONNECTING || Obj.socket.readyState === WebSocket.OPEN)) return;
if (typeof Config.WebSocketInfo != 'object') return;
if (!Config.WebSocketInfo.enabled) return;
try {
Obj.socket = new WebSocket(Config.WebSocketInfo.url);
Obj.socket.onmessage = Obj.socketOnMessage;
Obj.socket.onopen = function(e) {
// console.log("Web Socket Connection established!");
while (Obj.socketMessagesToSend.length != 0) {
Obj.socket.send(Obj.socketMessagesToSend.shift());
}
}
} catch (e) {
console.log('Could not connect. Is connection blocked by your content-security-policy?');
}
}