So recently I was testing stuff with Discord API (just for fun) but i kept on receiving from the heartbeat type "19" in the data object. I would like to know what exactly it meant and how to identify it later on.
Related
I'm writing a p2p chess game that sends 2 byte messages back and forth (e.g. e4 or c4). I'm considering the use of GAE Channel API. I noticed that this API causes the browser to send a heartbeat message to the server with POST URL https://849.talkgadget.google.com/talkgadget/dch/bind?VER=8&clid=...
That fires about every second. I won't be charged for the response data and response headers for those heartbeat requests correct?
Also, when I send data from the server to a browser over a channel, am I charged for only the json string itself or all http header/payload packets?
Google has a newer (and totally free!) API you should look at instead of the channel API (unless its restrictions cant be worked arround.)
GCM (google cloud messaging) is free, with a few restrictions like packet size (2kb in some cases) but it will handle everything for you (queuing, broadcast to all, broadcast to topics, one-to-one messaging, battery-efficient mobile libraries (android and iOS), native chrome support etc.
https://developers.google.com/cloud-messaging/
Make sure to also see this s.o. answer for GCM implementation tips: https://stackoverflow.com/a/31848496/2213940
Let's say we have several clients connected to App Engine using Channel API. Each client sends messages, which should be propagated to other conntected clients according to some rules. The tricky part is that clients may not be to the same App Engine instance.
Is there any way to push data from one instance to the others?
(Yes, I know about Memcache, but this would require some kind of polling.)
You're asking two questions here.
a. Can you push data from one instance to another without the use of polling. The answer is generally no.
b. Can one client send messages to the server that can be propagated to other clients? Yes, and this does not require propagating messages to other server-side instances.
Consider the Channel API as a service. Clients are connected to the Channel API service; they are not connected to any particular instance. Therefore any instance can send messages to any client.
You'll need to store the Channel tokens of your clients in the datastore, in some way that's queryable to match your rules.
Your client makes an HTTP request to send a message to your server.
The handler on the server queries for channel tokens that it needs to propagate the message to (either from memcache or datastore).
The handler on the server sends messages to all the clients.
If the list of destination clients is extremely large, you might want to do steps 3/4 in a task queue where the operation can run longer.
It does not matter what instance a client is connected to, that's hidden from you by the API.
Clients can only "reply" to message via standard HTTP commands, they don't actually have any way to respond via the channel API directly.
So Client A on server A1 wants to sent a message to client B on server B1.
Client A posts to a handler. That might be instance A1 or B1. It does not matter which as the server now passes the message on to client B whatever server client B is connected to via the Channel API.
The real point is that no App Engine instance has any data at all, in general. So it does not matter which instance you connect to, it might be the 99th instance or the very first to start up. So you have to design your application so that it's irrelevant what instance is in use.
Client sends message to server via HTTP.
Server sends message to N clients via the channel API.
Channel API does not make a fixed frontend-instance-to-client connection. Any frontend instance can push message to channel if it knows the channel ID.
What you need to do is pass messages cross-channel.
User one sends message normally to server (e.g. via GET)
Server looks up channel ID of second user and pushes the message
Repeat procedure in other direction: second user to first user.
I created a working Google Channel AP and now I would like to send a message to all clients.
I have two servlets. The first creates the channel and tells the clients the userid and token. The second one is called by an http post and should send the message.
To send a message to a client, I use:
channelService.sendMessage(new ChannelMessage(channelUserId, "This is a server message!"));
This sends the message just to one client. How could I send this to all?
Have I to store every Id which I use to create a channel and send the message for every id? How could I pass the Ids to the second servlet?
Using Channel API it is not possible to create one channel and then having many subscribers to it. The server creates a unique channel for individual JavaScript clients, so if you have the same Client ID the messages will be received only by one.
If you want to send the same message to multiple clients, in short, you will have to keep a track of active clients and send the same message to all of them.
If that approach sounds scary and messy, consider using PubNub for your push notification messages, where you can easily create one channel and have many subscribers. To make it run on Google App Engine is not that hard, since they support almost any platform or device.
I know this is an old question, but I just finished an open source project that uses the Channel API to implement a publish/subscribe model, i.e. you can have multiple users subscribe to a single topic, and then all those subscribers will be notified when anyone publishes a message to the topic. It also has some nice features like automatic message persistence if desired, and "return receipts", where a subscriber can be notified whenever OTHER subscribers receive that message. See https://github.com/adevine/gaewebpubsub#gae-web-pubsub. Licensed under Apache 2.0 license.
In the AppEngine Channel API, channels automatically close after 2 hours. We are handling this by rejoining the channel in the onError event.
Is there a chance the messages could get missed if they are sent while the channel is reconnecting?
Our scenario: We have an appointment scheduling system where appointments are booked elsewhere through an API. We use the channel to display new appointments on the schedule as they arrive. But I'm concerned that some appointments could get missed if they are booked during the time when a channel is closed and reconnected. Does the Channel API guard against this?
A little bit of background: the "client id" in the Channel API is used to create a transient XMPP endpoint. A given client id will always map to the same transient endpoint. So when you re-connect using a token to a channel created with the same client id, you are reconnecting to the same endpoint. Because of this you might see behavior where your client gets messages sent before recreating the channel. But there are no guarantees and we don't actively queue messages when they're sent to a channel with no listening clients.
In your case, could you return an up-to-date list of appointments as part of the same response that returns a new token?
You're not 'reconnecting' the channel, you're creating an entirely new one - so yes, messages could be missed. You should get an exception if you try to send a message to a closed channel, however.
Every example for GAE Chats uses some kind of polling. However, if my GAE app holds a list of clients (in the datastore if necessary), perhaps I could avoid polling by sending a message to all these clients. How can I achieve this?
If you are talking about HTTP, the short answer is that GAE does not currently support it. What I think you are asking about is sometimes called BOSH. Once WebSockets become more widespread, they will be an excellent solution for this problem.
In the mean time you might want to look at XMPP. Using XMPP you can avoid polling. Google has announced a Channel API (yet to be released) which will basically give you the same features as websockets.
You've probably seen some chat room examples...
Since you just want to send a message to users on your datastore (Tip: the IMProperty is great to store such data), it's just a matter of directly sending the message:
from google.appengine.api import xmpp
# `destination` is a list of JIDS
# `message` is a normal unicode string
xmpp.send_message(destination, message)
You can find a great tutorial on using XMPP by Nick Johnson here
Note that you can now use the App Engine Channel API for this: http://code.google.com/appengine/docs/python/channel/
You can create a channel for a given client using:
channel.create_channel(client_id)
Then when you want to update that client, send a message:
channel.send_message(client_id, message)
Basically each client will get a persistent connection that you can push messages over.