Queued messages
From EsWiki
Plugins can send queued messages to prevent problems caused by the Flash player's limitations on socket messages. If an application can keep the total number of socket messages per second below 20, there is no reason to resort to queuing. In the case of virtual worlds and real time games that require position updates on multiple users, queuing of the position updates at least is usually required.
Contents |
Overview
Each time that a plugin needs to send a message, it can decide whether to send it as a normal plugin message which is delivered immediately, or as a queued message. When a plugin uses message queuing, every so many milliseconds if there are messages in the queue for a user, those messages are bundled into a single message which is sent to the client. The client API unpacks the bundle, and as far as the client application knows the messages arrived separately, while Flash player thinks it was a single message. This makes it an excellent choice for applications with many users all constantly sending messages to the room via the plugin.
Start the Queue
The first decision to be made is how often the queued messages should be sent. A very common value for this is 200 milliseconds, which is often enough that when combined with tweening humans don't usually notice any jerkiness of motion. This means 5 queued messages sent each second, allowing plenty of leeway for other socket messages such as user variable updates, user list updates, plugin messages that need to be sent immediately, etc.
Choose a method in the plugin that executed a single time before clients start sending messages that would need to be queued. The init method is ideal here but your application may have a better choice. Add a line similar to this one, replacing the 200 with the number of milliseconds between queued messages that your application needs.
getApi().startQueue(200);
Destroy
Any plugin that starts a queue needs to stop it. Normally this happens in the destroy() method. At this time any unsent messages will be discarded, but if the room is being destroyed the messages would just confuse the client anyway.
getApi().stopQueue();
Send Queued Message
There are three different methods that can be used to send queued messages:
- sendQueuedPluginMessageToRoom
- sendQueuedPluginMessageToUser
- sendQueuedPluginMessageToUsers
In each case you have a choice of including an optional String messageName. If a messageName is included, any other message in the queue to the same user that has the same messageName will be dropped.
Let us assume an application that has 20 users in a room, each sending a position update every frame, so that there are about 30 position updates a second from each user. This is excessive of course, and if all those messages were broadcast immediately, that would be 600 messages a second and all the clients would disconnect due to the Flash player's limitations. If each of these messages is sent using sendQueuedPluginMessageToRoom without specifying a messageName, each client would end up processing all 600 messages over the course of the second, but the Flash player would be happy.
In many applications, the path a user takes to get from one position to another isn't important, so all the client needs is the most recent position for each user. For this situation, when a position update arrives at the plugin, the plugin should queue it using the username as the messageName. Using a queue frequency of 200 ms, this would mean that the client would only get 5 position updates a second for each user in the room, for a total of 100 messages to process (but the Flash player still thinking that there were only 5 messages).
Final Thoughts
Not all messages should be queued. Since the Flash player has no limitation on the number of outgoing socket messages, there's no reason to bundle messages on the client, although clients will often send position updates less often than every frame simply to save bandwidth and server processing time. Real time games require some messages to be broadcast immediately, such as "Player A grabbed item 3" so that item 3 can be removed from the board.
