New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 671588 link

Starred by 4 users

Issue metadata

Status: Fixed
Owner:
Leaves the project on 2018/03/02
Closed: Dec 2016
Cc:
Components:
EstimatedDays: ----
NextAction: 2016-12-26
OS: Windows
Pri: 1
Type: Bug-Regression



Sign in to add a comment

Error opening WebSocket in Service Worker

Reported by m.zd...@gmail.com, Dec 6 2016

Issue description

Chrome Version       : 55.0.2883.75
Other browsers tested:
Chrome 49.0.2623.75: OK
Chrome 54.0.2840.71: OK
Chrome 56.0.2924.14: FAIL

What steps will reproduce the problem?

(1) create new WebSocket in Service Worker

What is the expected result?

WebSocket should trigger 'open' event.

What happens instead?

WebSocket triggers 'error' event and 'close' event with code 1006 but no 'open' event.

 

Comment 1 by ajha@chromium.org, Dec 6 2016

Components: Blink>ServiceWorker
Labels: -Type-Bug -Pri-3 M-55 Pri-2 Type-Bug-Regression

Comment 2 by horo@chromium.org, Dec 6 2016

Components: Blink>Network>WebSockets
Cc: falken@chromium.org tyoshino@chromium.org ricea@chromium.org pbomm...@chromium.org
Labels: OS-Windows
cc'ing people who have more insights on websockets and service worker for further debugging.

Comment 4 by m.zd...@gmail.com, Dec 6 2016

Reproducible also on Linux.

Comment 5 by mek@chromium.org, Dec 6 2016

See https://github.com/w3c/ServiceWorker/issues/947 for some spec discussion around this topic (although the conclusion seemed to be that probably this should just be supported).
Labels: prestable-55.0.2883.75

Comment 7 by ricea@chromium.org, Dec 7 2016

If this were to work I suppose the WebSocket would have to stay alive when the ServiceWorker was terminated, and start the ServiceWorker again when a message was received. This is rather radically different from how we manage WebSockets at the moment.

There is also a resource exhaustion issue. You can have at most 255 connected WebSockets total per profile. If you use a proxy that number will be lower.

The alternative of creating the WebSocket afresh every time the ServiceWorker starts seems inefficient and pointless. You might as well just transmit the data using fetch(). A WebSocket handshake will be strictly more expensive than doing a single fetch().

Keeping the ServiceWorker alive while a WebSocket connection exists goes against the ServiceWorker principle in my opinion. Keeping the ServiceWorker alive if the WebSocket is connected *and* there is a page open using it might be viable as a method for achieving WebSocket multiplexing (but maybe a SharedWorker makes more sense here).

Having said that, if the interface exists but doesn't work that is obviously bogus.
Labels: -Pri-2 Pri-1
Do you know why this used to work in M54 and fails in M55? We (Blink>ServiceWorker triagers) treat regressions as P1 by default.

Comment 9 by ricea@chromium.org, Dec 7 2016

I've no idea why it stopped working, but it should not be too hard to find out:

1. Port the existing Worker tests to ServiceWorker, and pick one that fails.
2. Use that failing test with bisect-builds.py to find the CL which broke it.

@tyoshino, can you take this?
Cc: gov...@chromium.org
Labels: ReleaseBlock-Stable
Given this is the regression which is broken in M55, I am marking the bug as stable blocker for M55 until we figure out what caused this regression.

@tyoshino and  ricea@ can we get an update soon we are planning M55 release soon and if we need this to be fixed we need to get the fix in by Friday.
[Bulk edit]

URGENT - PTAL ASAP.

This issue is marked as a stable release blocker for this week M55 Stable release cut, pls make sure to land the fix and get it merged to release branch ASAP.

Know that this issue shouldn't block the release?  Remove the ReleaseBlock-Stable label.


Thanks!
Owner: tyoshino@chromium.org
I'll investigate this today once I get to the office, and report feasibility, etc.

As noted above, it's still under question on the spec side whether WebSocket should be supported inside a SW context. I guess the adoption of WS in SW is not so big, but we don't have any UMA, etc available to measure it.

m.zdila@gmail.com, and others watching this bug, has this broke any production app of yours? Do your apps have fallback in case WS in SW is not working?

Though we've never advocated this kind of usage, WebSocket could be theoretically used for getting push from cloud and show notifications. But, ... since unlike subscription to FCM/GCM/etc. using push manager, WebSocket may just get killed when the SW is killed, I guess this is not used much in production.

Cc: yhirano@chromium.org
+yhirano
blink::WebSocketHandleImpl::onConnectionError() is called right after connect() and flowControl() of WebSocketHandleImpl. No vlog seen for WebSocketImpl. It looks this is due to mojofication of WebSockets.
Bisecting
Status: Assigned (was: Unconfirmed)
> It looks this is due to mojofication of WebSockets.

This guess was wrong. The mojofication revision works.
423768 bad
419011 bad
416700 bad
416176 bad
415914 building this now
415653 good
414607 good

Moving to the office
Bisect done. I think the culprit is r415799.

423768 bad
419011 bad
416700 bad
416176 bad
415914 bad
415848 bad
415815 bad
415799 bad
415795 good
415791 good
415783 good
415653 good
414607 good
tyoshino: Thanks for bisecting. Don't you mean r415798?
Oops, sorry. Right. r415798

It seemed that a change in this file is the culprit.
https://codereview.chromium.org/2284473002/diff/200001/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp

This changed WebSocket to use the InterfaceProvider of document()->frame() if any.

Reverting this part fixes the issue and keeps the other WebSocket layout tests also working. With some help by yhirano, I'm trying to check if it's fine to revert this part. If it's ok, the patch to merge will be just 1 line.
Fix is ready. CQ dry run ongoing.
https://codereview.chromium.org/2564493002/
Status: Started (was: Assigned)
zdila has explained their use case of WebSockets in SW in this comment. But not sure if it's reasonable enough.
https://github.com/w3c/ServiceWorker/issues/947#issuecomment-265385108
We should continue the discussion at the spec side.

But given this is a regression, the spec is currently saying that it's available in a SW (see "Exposed=(Window,Worker)" in the IDL. "Worker" includes SW. https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface), and there's a real user, ...

Oh, the fix WebSocket third-party cookie blocking ( bug 634311 ) is depending on r415798. We shouldn't just revert it but revert it only for ServiceWorkers.
The issue in #25 has been addressed in the patch.
Labels: -ReleaseBlock-Stable
Considering the possible impact of this regression and the value of delivering all the features/improvements/fixes included in M55 sooner, I've removed the ReleaseBlock-Stable label.

We can still include the fix after getting it baked/verified in canary in any stable refresh if any depending on new rationale and data points about the impact we get.
Project Member

Comment 29 by bugdroid1@chromium.org, Dec 9 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/dd3b58a1f0073215d58bcb8dc216b89e546bc9f7

commit dd3b58a1f0073215d58bcb8dc216b89e546bc9f7
Author: tyoshino <tyoshino@chromium.org>
Date: Fri Dec 09 01:21:27 2016

Make WebSocket available again in service workers

The patch https://codereview.chromium.org/2284473002/ was basically a
refactoring change, but it also included a change that it started using
the InterfaceProvider instance of the LocalFrame of the associated
Document if any. However, in a service worker, the LocalFrame returns
the empty provider obtained by calling
InterfaceProvider::getEmptyInterfaceProvider(). This is because the
WebEmbeddedWorkerImpl used for service workers doesn't override
the WebFrameClient::interfaceProvider() method which returns nullptr by
default while one on the WebSharedWorkerImpl and RenderFrameImpl
returns an effective InterfaceProvider instance.

This patch fixes the issue by changing the code to use the
InterfaceProvider of the LocalFrame only when it's not the empty
provider.

R=falken@chromium.org
TBR=yhirano@chromium.org
BUG= 671588 

Review-Url: https://codereview.chromium.org/2564493002
Cr-Commit-Position: refs/heads/master@{#437406}

[add] https://crrev.com/dd3b58a1f0073215d58bcb8dc216b89e546bc9f7/third_party/WebKit/LayoutTests/http/tests/serviceworker/websocket/resources/simple.js
[add] https://crrev.com/dd3b58a1f0073215d58bcb8dc216b89e546bc9f7/third_party/WebKit/LayoutTests/http/tests/serviceworker/websocket/websocket-in-service-worker.html
[modify] https://crrev.com/dd3b58a1f0073215d58bcb8dc216b89e546bc9f7/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp

Status: Fixed (was: Started)
Going to request merge r437406 to M56 beta branch after getting it baked.
 Issue 676310  has been merged into this issue.
NextAction: 2016-12-26
Labels: Merge-Request-56
Project Member

Comment 35 by sheriffbot@chromium.org, Jan 19 2017

Labels: -Merge-Request-56 Merge-Review-56 Hotlist-Merge-Review
This bug requires manual review: We are only 11 days from stable.
Please contact the milestone owner if you have questions.
Owners: amineer@(clank), cmasso@(bling), gkihumba@(cros), bustamante@(desktop)

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Merge-Review-56 Merge-Approved-56
Approved for merge into M56
Project Member

Comment 37 by bugdroid1@chromium.org, Jan 20 2017

Labels: -merge-approved-56 merge-merged-2924
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/31c0d697c6d885cee1084c1c30e4f04d2e32e36a

commit 31c0d697c6d885cee1084c1c30e4f04d2e32e36a
Author: Takeshi Yoshino <tyoshino@chromium.org>
Date: Fri Jan 20 06:35:15 2017

Make WebSocket available again in service workers

The patch https://codereview.chromium.org/2284473002/ was basically a
refactoring change, but it also included a change that it started using
the InterfaceProvider instance of the LocalFrame of the associated
Document if any. However, in a service worker, the LocalFrame returns
the empty provider obtained by calling
InterfaceProvider::getEmptyInterfaceProvider(). This is because the
WebEmbeddedWorkerImpl used for service workers doesn't override
the WebFrameClient::interfaceProvider() method which returns nullptr by
default while one on the WebSharedWorkerImpl and RenderFrameImpl
returns an effective InterfaceProvider instance.

This patch fixes the issue by changing the code to use the
InterfaceProvider of the LocalFrame only when it's not the empty
provider.

R=falken@chromium.org
TBR=yhirano@chromium.org
BUG= 671588 

Review-Url: https://codereview.chromium.org/2564493002
Cr-Commit-Position: refs/heads/master@{#437406}
(cherry picked from commit dd3b58a1f0073215d58bcb8dc216b89e546bc9f7)

Review-Url: https://codereview.chromium.org/2649463003 .
Cr-Commit-Position: refs/branch-heads/2924@{#815}
Cr-Branched-From: 3a87aecc31cd1ffe751dd72c04e5a96a1fc8108a-refs/heads/master@{#433059}

[add] https://crrev.com/31c0d697c6d885cee1084c1c30e4f04d2e32e36a/third_party/WebKit/LayoutTests/http/tests/serviceworker/websocket/resources/simple.js
[add] https://crrev.com/31c0d697c6d885cee1084c1c30e4f04d2e32e36a/third_party/WebKit/LayoutTests/http/tests/serviceworker/websocket/websocket-in-service-worker.html
[modify] https://crrev.com/31c0d697c6d885cee1084c1c30e4f04d2e32e36a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp

Watching betabuilders
Win bot finished without any new failure.
Mac done. All green.
Linux too.

Done

Sign in to add a comment