Issue metadata
Sign in to add a comment
|
WebSocket.onmessage event doesn't fire for messages that arrive before the SafeBrowsing check completes
Reported by
v.or...@querix.com,
Nov 19 2017
|
||||||||||||||||||||||
Issue description
UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Steps to reproduce the problem:
1. Create websocket object and add event listeners to it
var sock = new WebSocket("ws://localhost:9090/spoll?cid=" + cid + "&pid=" + pid);
sock.onopen = function(e){console.log('onopen',e);}
sock.onmessage = function(e){console.log('onmessage',e);processMessage(e.data);}
What is the expected behavior?
1. onopen event is fired
2. onmessage event is fired
What went wrong?
onopen event handler always works okay, while onmessage event handler is not firing periodically.
Did this work before? N/A
Does this work in other browsers? Yes
Chrome version: 62.0.3202.94 Channel: stable
OS Version: 10.0
Flash Version:
Problem is reproducing from time to time starting with Chrome version 62 and looks related to the heavy CPU load/insufficient RAM - it is reproducing more often in VirtualBox (Win7x64 1 CPU 4Gb RAM) rather than in Win10 16Gb RAM.
,
Nov 20 2017
@Reporter: Could you please provide sample URL or test file to check this issue. This would help in further triaging of this. Thanks!
,
Nov 20 2017
,
Nov 21 2017
A couple of additional questions: 1. Is this happening on the main page or in a worker? 2. Are the messages text or binary. I've looked at recent changes to the WebSocket implementation in Blink (back to June) and there's nothing I can see that could have caused this. That doesn't rule out a change somewhere else, but I would expect that to affect other event handlers and not just WebSocket onmessage. Without a way to reproduce this I don't think there's anything we can do.
,
Nov 21 2017
,
Nov 21 2017
1. It is happening on the main page. 2. Messages are in JSON format I'm trying to narrow problem on our side and provide the way to reproduce. (So far the most "stable" environment where problem reproduces more often than in others is Oracle VirtualBox Win7x32 1CPU, 2Gb RAM).
,
Nov 21 2017
Thank you for providing more feedback. Adding requester "sc00335628@techmahindra.com" to the cc list and removing "Needs-Feedback" label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Nov 21 2017
#6: Since it happens more in memory-constrained environments, I suspect a garbage-collection related problem. When you reproduce the issue, are you using a script such as the one in #1 that retains a reference to the WebSocket object?
,
Nov 21 2017
There is a layout test, https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/http/tests/websocket/websocket-pending-activity.html, which covers a related case, but there is no record of it failing.
,
Nov 22 2017
#8: Yes, websocket object is retained.
More precisely, real code without insignificant details is:
root.sock = {
attach: function() {
this.sock = new WebSocket("" + prot + conf.s + pp + "spoll?cid=" + conf.cid + "&pid=" + conf.pid);
this.sock.onopen = function() {console.error('>>>ONOPEN',arguments);};
this.sock.onmessage = function(e) {console.error('>>>ONMESSAGE',e);};
}
}
Where 'root' is the global variable.
,
Nov 22 2017
Thank you for providing more feedback. Adding requester "ricea@chromium.org" to the cc list and removing "Needs-Feedback" label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Nov 22 2017
I compared websocket-pending-activity.html with our code. The difference which may be important is that websocket receives message from the server without prior send().
,
Nov 22 2017
#10 Thanks. I've been assuming from your description that some messages are skipped, but the following messages still arrive. Is that correct?
,
Nov 22 2017
#13: Actually our system is built so, that first message sent from the server to the client boots up the application. Without first message received the client application in the browser just remains uninitialized. While the server doesn't initiate message sending to the client - it only responds to the client. === So, the answer is: there are no more messages after first one missed.
,
Nov 24 2017
The code adding devtools entries for WebSocket frames is very close to the code firing onmessage events, so I feel it strange.
,
Nov 24 2017
#15 I noticed the same thing. The Suspend/Resume code has been refactored recently. If the WebSocket is getting suspended but never resumed, it might explain the observed behaviour. +hajimehoshi who did the refactoring.
,
Nov 30 2017
Attached the client-server test which reproduces problem with websocket 'message' event not firing. Important note: problem occurs more often on the Windows systems with limited memory.
,
Dec 1 2017
That's by far the most attractive bug repro I've ever seen! I've so far tried it on Linux, but as expected it didn't reproduce the issue. I'm installing nodejs on my Windows machine to see if I can repro it there. If not, I'll set up a virtual machine.
,
Dec 4 2017
I tested it on my Windows 10 machine for a few thousand connections. It didn't reproduce, but since it has 32Gb of RAM that wasn't a big surprise.
,
Dec 4 2017
Will you try VirtualBox with 1Gb RAM?
,
Dec 4 2017
I plan to try it with VMWare, since that is what I have available. Hopefully that won't make any difference. It may take me a few days to get it set up.
,
Dec 15 2017
你好,我的浏览器版本也为Chrome/62.0.3202.94。我也遇到了websocket onmessage没有被chrome触发的情况,但在chrome->devTools->ws->frames内是有服务器端发送的消息。我的情况为:首次打开链接,websocket open之后,不会触发onmessage,但是刷新页面之后就可以了。我这边目前可以稳定复现BUG,复现方法就是清空chrome的所有缓存,历史记录,并退出chrome。然后再次打开,就可以复现了。
,
Dec 15 2017
Machine translation of #22: """ Hello, my browser version is also Chrome / 62.0.3202.94. I also encountered websocket onmessage not chrome triggered situation, but in chrome-> devTools-> ws-> frames there is a message sent by the server. My situation is: for the first time to open the link, websocket open, will not trigger onmessage, but refresh the page after it. Now I can reproduce the stable BUG here, the reproduction method is to clear all chrome cache, history, and exit chrome. Then open again, you can reproduce. """ Thank you for the feedback. I have not yet managed to reproduce, so I will try your technique.
,
Dec 15 2017
又经测试发现如下问题:
var ws = new WebSocket('ws://xxx.xxx.china.com.cn:port/scene/push/6666');
在这个路径下,websocket不会触发onmessage。
服务端代码:
let wss = new WebSocketServer({
port: port
}, done);
wss.on('connection', (ws) => {
try{
console.log("readyState:",ws.readyState)
ws.send(`ok`);
}catch(e){
console.error(`send error `+e);
}
});
端口号后边跟上边所写的path(/scene/push/6666),客户端就会出现不能触发onmessage的问题。如果换成其他path,就没有类似问题。
,
Dec 15 2017
又经测试发现如下问题 1.websocket的链接在端口号后边跟特定的path(/scene/push/6666),客户端就会出现不能触发onmessage的问题。如果换成其他path,就没有类似问题。 2.hosts配置,例如:xxx.xx.156.59 xx.x.china.com.cn 当配置为xx.x.china.com.cn时,也是不会触发onmessage的。配置为xx.x.china1.com.cn时就不会有类似问题
,
Dec 18 2017
Reproduced on a Windows 7 VM with 2GB RAM. Sorry for the delay; it took me longer than expected to get it set up. I haven't investigated a lot yet, but some early observations: * It strongly appears to be memory-related. The number of WebSocket connections attempted can be adjusted with the count= parameter in the URL. It rarely (never?) happens with small numbers. * I've only seen the first WebSocket fail. * It happens more often with DevTools open, and with lower socket counts. * WebSocket connection appears to still be open, just the message event is missing. Note on the repro: nodejs tends to exit with an ECONNRESET error when the page is reloaded. Adding an 'error' handler to the ws object fixes it. I will do more debugging.
,
Dec 18 2017
Confirmed the issue still reproduces in the latest canary, 65.0.3298.0.
,
Dec 18 2017
Nothing obviously unusual in the netlog. Message is received as usual. Connection remains open.
,
Dec 20 2017
socket packet received as usual. and can see frames with dev devTools->network>frames. but some times onmessage cannot be fired with first message. And Problem is reproducing easily by waiting some time between 'new Websocket()' and setting onopen and onmessage with path like xxx.xxx.china.com.cn:port/scene/push/6666
,
Dec 20 2017
#29 The onopen event handler is not guaranteed to be called unless it is set synchronously. This is the same in all browsers. I think it is unrelated.
,
Dec 21 2017
the open set synchronously.but just stalled some time ,such as
'
let startTime = Date.now();
while(Date.now()-startTime<2000){};
ws.onopen=function(event){}
ws.onmessage=function(event){}
'
the onopen always be fired but onmessage sometimes not
,
Jan 10 2018
I've finally tracked down the root cause for the bug. The problem is with the SafeBrowsing check. The onopen event is delayed until the SafeBrowsing check completes, but messages can still be received. In this case they will be ignored without the onmessage handler being called. I think the simplest fix is to postpone calling DocumentWebSocketChannel::FlowControlIfNecessary() until the SafeBrowsing check completes. This should prevent the browser process from sending any messages until the render process is ready for them. The issue was introduced in M61. In most cases the SafeBrowsing check easily wins the race, which is why this issue is so hard to reproduce.
,
Jan 10 2018
,
Jan 18 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/417005badf1ddda28af2b08297692cfafb9a9ffc commit 417005badf1ddda28af2b08297692cfafb9a9ffc Author: Adam Rice <ricea@chromium.org> Date: Thu Jan 18 15:56:23 2018 WebSocket: Don't provide flow control quota until opened This prevents the browser sending WebSocket messages before any handshake throttle has completed, which ensures the onmessage event fires. This does result in a tiny regression in the time after connection before the first message can be received by Javascript, but it should not be significant in normal usage. Also add checks of state_ to DOMWebSocket::DidReceiveBinaryMessage() to match the ones in DidReceiveTextMessage(). BUG= 786776 Change-Id: I10762cd379660cdc8f07601ac2abdf04371af207 Reviewed-on: https://chromium-review.googlesource.com/867804 Reviewed-by: Takeshi Yoshino <tyoshino@chromium.org> Commit-Queue: Adam Rice <ricea@chromium.org> Cr-Commit-Position: refs/heads/master@{#530149} [modify] https://crrev.com/417005badf1ddda28af2b08297692cfafb9a9ffc/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp [modify] https://crrev.com/417005badf1ddda28af2b08297692cfafb9a9ffc/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp [modify] https://crrev.com/417005badf1ddda28af2b08297692cfafb9a9ffc/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h [modify] https://crrev.com/417005badf1ddda28af2b08297692cfafb9a9ffc/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannelTest.cpp
,
Jan 19 2018
Fix verified with the latest Chrome Canary.
,
Jan 29 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/a79f65e9efd219f8a66d2d82fc745a09b650ceb4 commit a79f65e9efd219f8a66d2d82fc745a09b650ceb4 Author: Adam Rice <ricea@chromium.org> Date: Mon Jan 29 05:24:59 2018 Add layout tests for WebSocket handshake throttle Test handshake throttling from layout tests. This involves adding a test-specific throttle, content::TestWebSocketHandshakeThrottle, which is used when the --run-layout-tests option is supplied. It looks for a content-shell-websocket-delay-ms query parameter in the WebSocket URL and applies the specified delay if it exists. As a result it does not interfere with other tests. Includes a regression test for crbug.com/786776 . This verifies that a message sent by the server is delivered even when the open is delayed by throttling. BUG= 786776 Change-Id: If8b2be86ac617d037bc1ee0059512b5d950a313d Reviewed-on: https://chromium-review.googlesource.com/867806 Commit-Queue: Adam Rice <ricea@chromium.org> Reviewed-by: Peter Beverloo <peter@chromium.org> Reviewed-by: Takeshi Yoshino <tyoshino@chromium.org> Cr-Commit-Position: refs/heads/master@{#532329} [modify] https://crrev.com/a79f65e9efd219f8a66d2d82fc745a09b650ceb4/content/shell/BUILD.gn [modify] https://crrev.com/a79f65e9efd219f8a66d2d82fc745a09b650ceb4/content/shell/renderer/layout_test/layout_test_content_renderer_client.cc [modify] https://crrev.com/a79f65e9efd219f8a66d2d82fc745a09b650ceb4/content/shell/renderer/layout_test/layout_test_content_renderer_client.h [add] https://crrev.com/a79f65e9efd219f8a66d2d82fc745a09b650ceb4/content/shell/renderer/layout_test/test_websocket_handshake_throttle.cc [add] https://crrev.com/a79f65e9efd219f8a66d2d82fc745a09b650ceb4/content/shell/renderer/layout_test/test_websocket_handshake_throttle.h [add] https://crrev.com/a79f65e9efd219f8a66d2d82fc745a09b650ceb4/third_party/WebKit/LayoutTests/http/tests/websocket/throttling.html |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by v.or...@querix.com
, Nov 19 2017