Intermittent error code 400, description "" on client connecting to channel
Asked Answered
S

3

5

My Google App Engine app, which uses the Channel API works well some of the time. Intermittently, though, the js code connecting to the channel generates an error. In socket.onError, the error code is set to 400 and the description is set to an empty string. I have checked that the token being used to connect is valid. I also tried recreating the channel in socket.onError, by first calling socket.close() but that does not seem to work. Often there is a series of failures before a success. The client js is running on Safari on iOS. Any ideas on how to fix or work around the problem will be welcome. Right now, my best workaround is to keep trying till I succeed, increasing the interval between attempts on each failure. The server side presence API does not help, since the 'connected' hook is not called reliably.

Syck answered 19/12, 2012 at 23:6 Comment(0)
S
4

It is known issue http://code.google.com/p/googleappengine/issues/detail?id=4940 and it was accepted. As you see the status of issue is not fixed. Feel free to star it.

Sardinian answered 20/12, 2012 at 0:0 Comment(1)
Thanks. In response to the comments in that issue: 1. I tried the proposed workaround of "pinging" an established channel but found that it does not prevent the error. 2. Resetting the client id does not help, sometimes the error occurs with new connections.Syck
S
2

I know double posting is bad (issue starred & comment posted)... but I suspect this thread might get more attention than the issue comments ^^

As far as we are concerned, it's at the very least a documentation issue:

https://developers.google.com/appengine/docs/java/channel/javascript still states " An onerror call is always followed by an onclose call and the channel object will have to be recreated after this event"

It is only true for, as far as we have guessed, error codes 400 and 401 (which are strings, not numbers, btw, so beware of === in the js code).

It is untrue for other error codes (we have logged at least the -1 code).

There should be a documentation covering all error codes and their (expected) management.

Atm, we have a "channel manager" that reuses the same channel token when code is not 400 or 401, and that makes sure onclose is called once and once only per Socket.

Before that, we were trying to close properly, and reopen (new underlying Socket) with a shiny brand new token: usually we got an error 400 followed by an error -1.

FUI we first detected this behavior on iOS, quite recently (regression ftw? Before that iOS was dandy). Reopening the socket after a code -1 is not a panacea: sometimes it will succeed (onopen properly called), and then fail silently (no message received, no onerror called).

Generally, we also noticed more consistent behavior on desktop browsers than mobile ones, across all user agents and platforms (more on that: yay! Other issues incoming! Especially android...)

OK, this post might have been useful after all. Thx!

[EDIT: corrected a mistake... we don't reuse the channel object nor the socket object, only the token]

Singhal answered 15/1, 2013 at 10:20 Comment(5)
I am observing this problem on iOS also. Have you resolved the issue on iOS using the method outlined above? If so, then could you clarify your solution. As I understand it: 1. For errors 400 and 401, you a) recreate the socket. b) ensure that onClose is not called twice 2) For error -1, you 'reuse the socket' (what does that mean exactly)?Syck
1)a) Yes. That means we explicitly call the close method of the goog.appengine.Socket object if our internal state allows it (see below). Then we recreate a Channel then a Socket object, etc. (the whole workflow)Singhal
1)b) After creating a Channel object we pass an object containing the 4 expected callbacks (onopen, onclose, onmessage, onerror) to the open method. The callbacks are all closures that allow us to maintain a global consistent state for the "current channel environment". Use your own preferred pattern... ^^Singhal
2) When we get an error that we don't interpret as "token expired or whatever => need a new token", we do exactly the same (close, recreate, reopen) but with the same token. We don't reuse the same underlying object, sorry for the confusion... Edited main post to reflect that!Singhal
I tried your method, but it does not address the issue for us.Syck
T
1

I contacted Google support about this issue.

When a error 400 happens it's because a timeout (one minute it seems) happened. This timeout generates a disconnection (url disconnected is called and you should remove the client id of the database). Then, a new channel must be created with a new client id.

But it is not enough. We have to use this jquery command line : $('#wcs-iframe').remove();
Just inside the js onerror function and before to try to recreate the channel.

Tankage answered 28/11, 2014 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.