Implementing Realtime in Streak Using the AppEngine Channel API

This is another post for the developers out there that are curious as to how we implemented realtime collaboration in Streak. Implementing this feature in Streak had some unique challenges since we are an extension running on top of Gmail — a bit different than your usual app.

First thing to do is creating the communication framework itself. You can use sockets, polling, etc. Fortunately we didn’t have to worry about any of that as we’ve had a team of some very smart Google engineers working on this very problem. Enter the Channel API. With the Channel API getting up and running on both the client and the server is pretty straightforward. Usually.

Streak exists as an extension and is inside of Gmail; a very complex environment. The main issue is that you can only have one Channel on a page at one time. The Channel API uses the same infrastructure as Google Chat which means that the one Channel is already being used up. Even if GChat wasn’t using the Channel tech, we wouldn’t want to embed our channel in the main Gmail context since another extension may want to use Channel tech which would cause collisions.

Question: Where can our Channel connection exist?
Answer: The extension’s background page

Every extension has a background page which is a full DOM object that can be manipulated like any other page. We can add the Channel script to the background page, set it up with the proper token and voìla we have realtime. One problem. There’s only one background page for the extension and you can have multiple Gmail tabs/windows open at once.

We resolved this by using iframes. Whenever our system initializes and wants to create a new realtime connection with the server, we create a new iframe inside the background page. Since the iframe exists on the same domain as the background page we can manipulate it from the outside, so we then embed the Channel javascript inside the iframe and then get access to the resulting Channel object. It sounds crazy and it is.

Astute readers may notice that since the background page is persistent we have to make sure to clean up the iframes and connections when the corresponding Gmail tab is closed or navigated away from. Rest assured that we do this.

The technique works great in both production and development environments, and it even works well in Safari…