I have an update on plans to migrate off the channel APIs. I looked at both socket.io and sockjs, and neither one of them turned out to be acceptable. socket.io's error handling has some serious issues, and sockjs doesn't pass cookies in the connection request (intentionally - they claim it's a security hole if anyone does that, but they're making assumptions about cookie handling that in my case aren't true).
So here's where I ended up: - GAE instance continues as usual, for now - Node.js instance runs a low-level web socket implementation. I used websocket-node, but ws probably would have worked as well. - Node.js additionally runs a low-level Apple push notification implementation - On the client, which is a hybrid iOS app, I have a native (Objective-C) implementation of the web socket client, called SocketRocket. SocketRocket, like socket.io, has some error handling issues, but there's no other real option and I was able to work around them. - The HTML layer then talks to the native layer over a local-http bridge (intercepted using NSURLProtocol subclassing, which is a standard trick I've used in a bunch of other places) I used an Objective-C library rather than the UIWebView implementation of WebSocket because I'm supporting older iOS devices that don't have WebSocket support. However, this tradeoff means that I don't get cross-browser support, since many browsers don't have sufficient support for WebSockets to connect to the service (websocket-node only supports the latest RFC versions of the WebSocket protocol, not earlier Hybi versions). It all works pretty well. I now understand why the connection state works the way it does in GAE; there is almost certainly a proxy server somewhere in GAE land that's holding the channel connection separate from the GAE app itself. However, given that architecture there are a bunch of things that the Channel API failed on, which were pretty trivial to deliver in my replacement: - I can send to multiple clients in one request (fan-out) - I can send multiple messages in one request (batching) - I can instantly fall back to Apple push notifications if a client is not connected (and the message format is the same, so the application level in the client doesn't have to care how the message was delivered) - The request is synchronous so I get a result status back, with individual reporting on each client and each message -- Note though that the result status isn't bulletproof; it just reports connection up/down at the time Node.js issues the socket write. Since the socket write is asynchronous, it won't report errors that happen after dispatch. But it's good enough for my purposes. Some of the tradeoffs I've made mean that the work I've done isn't necessarily applicable to another project. So I'm not planning to post this e.g. to github for now. However, I wanted to post what I've done in case others want to pursue a similar path. The node.js service is only about 100 lines of code; most of the tricky bits had to do with shunting events around on the client and providing a proper abstraction for SocketRocket's error reporting. Cheers, - Kris -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To view this discussion on the web visit https://groups.google.com/d/msg/google-appengine/-/OLnVuy4jr8IJ. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
