Hi,

I'm checking out the eagerly anticipated Channel API facility in the
1.4.0 pre-release and have some questions while we're waiting for
documentation (I'm not in the Trusted Testers group).


Background - what I've gathered:
server side setup:
- all channels are automatically private to your app, but each channel
name can only have a single client listening to it
- no changes needed to app.yaml or similar to declare jsapi handler
(below) or pre-declare channels etc
- channels are created on first use but then accessible by any server
page by simply knowing the channel name (subject to timeouts etc)
- to make a simple "one channel per user" I use something like
try:
from google.appengine.api import channel
except:
channel = None
and then when my client first connects a make a channel named after the
user
if channel:
channelName = str(users.get_current_user())
channelId = channel.create_channel( channelName )
and push this channelId to my client (AJAX or in the generated
HTML/script pages)... this is basically a token for the current valid
consumer of the named channel


client side setup:
- add the script "/_ah/channel/jsapi" to your client somehow, eg
<script type='text/javascript' src="/_ah/channel/jsapi" />
- the dev server will return a page of JS code that implements the API
below by polling a special URL once a second or so, on production the
jsapi request actually redirects to
http://talkgadget.google.com/talkgadget/channel.js which makes a hidden
iframe and does proper long requests
- either way, you'll have pulled in a block of code, but you just need
to use the new goog.appengine.Channel class
- make a channel object with the channelId as created on the server
var mychannel = new goog.appengine.Channel( myChannelId );
var mysocket = mychannel.open();
mysocket.onmessage = function(msgevt) {
var data = msgevt.data;
// do what you want for each message - data is the string that is given
to send_message()
}


server side publish:
- to push a message onto the channel, simply call channel.send_message()
channelName = str(users.get_current_user())
channel.send_message(channelName, "some message") # I push a string of
JSON encoded data here myself
noting that you specify the channel name, NOT the channel ID
- be prepared to catch an exception on the above if a prior call to
your server code hasn't recently created the channel first


Now the above works fine for me with the dev server (and I hope will
just work when 1.4 goes live in production), but I have some questions
or statements of my understanding and would appreciate indications as
to their validity:


- is it true that each client is currently limited to opening a single
channel ?


- it seems that if a user starts another session with my server (ie
logged in twice from different browsers etc) then the 2nd call to
channel.create_channel() on the server with the same channel name will
allocate a new channelId that effectively disconnects the first
session... ie each channel is a strict "deliver once" message system,
NOT "deliver once to each reader" (this isn't a complaint, but a
question of intent)


- if I want to send a single logical message to multiple users, and/or
to multiple sessions for a single user, I should manage the channel
names myself per connected client, and send the message to as many
channel names as I think appropriate to get it once to each client


- messages sent after a client disconnects but before the channel
itself times out are queued up with the channel name and sent once a
client connects to that channel - do these expire after some time or
accumulate indefinitely ?


In short, what I think I need to do is
- when my web-app starts, the client makes a unique (essentially
random) ID and starts a new session with the server
- the server creates a channel for that user's session (eg channel name
is username+"_"+sessionID) and returns it to the client and also stores
the channel name in the database (or similar) for that user
- when something happens on the server such that I want to notify the
user, I retrieve their current valid channel names from the db and send
the message to each of their channel names
- if I want to notify multiple users, I do the above for each user in
turn
- if any of those channel names has timed out (client has disconnected
some time ago), the send_message call will throw an exception - I can
then delete the channel name from the db (to avoid trying to send any
more)
- the client agent regularly (once an hour or so) signals it's still
interested in events by telling the server it's still listening to the
queue, the server maybe pushes a "no-op" event to the channel to keep
it alive, and if this send_message() call throws an exception (channel
has timed out) then I can make a new channel with the specified name
and return them a new channel ID (ie they re-subscribe). At this stage,
because we don't know how long they've been disconnected, they should
re-read their state in full (effectively this act as if starting a new
session).
- do I need to worry about messages sent to channels which will never
be read (client disconnects, new message is sent) by doing some kind of
clean-up or can I assume they'll just be silently dropped sometime ?


This fits in fine with a use case of using channels to receive
notifications for some server side state changes while they're
connected (active), but not between sessions - that is, when a client
first connects it should read the current state in full, and use
channels only to be told about changes to that state during a session.
Does this look like "reasonable use" of the Channel API or am I abusing
some aspect of it ?? I could do something like every 10 minutes push
a "let me know you're still there" event to every channel, and then
delete my record of channels where the client hasn't sent some kind of
AJAX "yeah, I'm here, just idle" response since the last check... but I
can't tell at this stage whether that would be a good idea or the
complete opposite with regards to "playing nicely with the
infrastructure"....


Thanks in advance for any illumination


Cheers


--
Tim

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
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.

Reply via email to