Errai: The browser as a platform

Monday, October 7, 2013

More Errai Basics -- Climb on the Magic Message Bus!

In my last post, I talked about Errai CDI Events and began showing how they can be used to implement part of a typical lobby page for a multiplayer web-game. Near the end we encountered a typical use case that could not be handled by Events. As promised, I will now discuss how the Errai Message Bus can be used by the server to target a subset of the connected clients.

The Problem

To quickly recap: we have a set of clients in a game room lobby. We want Client A to invite Client B to a game. We've already figured out how to send an invitation event from Client A to the server, but we need a way to relay this invitation to Client B without broadcasting it to all the other clients.

Some Message Bus Basics

Service Endpoints

The Errai Message Bus is used to send messages between service endpoints. Defining a service endpoint requires only two things:
  1. Subject: A string (not necessarily unique), used by senders to address messages to this endpoint
  2. Callback: A method to be invoked by Errai when a message to this endpoint is received
When an endpoint is created we say that code has subscribed to the given subject. It is possible to dynamically define service endpoints, but as with most features of the framework the declarative syntax is preferable. Here is an example declaring a service in Errai.

It is also possible to annotate methods, such that a class may offer multiple services.

Sending a Message

To send a message we construct it with the MessageBuilder and then send it with the MessageBus like so.

It is possible to send objects with a message by adding parts. In the following example we will send a Greeting object to everyone subscribed to the subject "LonelyPeople".

Message Visibility

As with Errai CDI Events, there is only one degree of visibility of message. If the server sends a message to the subject "ErraiLovers", every subscriber to this subject will receive the message. But if a client sends a message to "ErraiLovers", only subscribers on that same client and the server will receive it.

Back to the Lobby

As you may have already guessed, a simple way to deliver messages to a single client is to dynamically subscribe them to a unique service endpoint.

Using Unique Ids

Here is the simple model used in Errai Block Drop that can be used to establish a direct line of communication to a single client.
  1. When a client first joins the lobby in Block Drop, they fire a CDI Event to the server
  2. The server generates a unique id and adds the client to the lobby
  3. The server fires back the unique id using a Conversational Event (which will only be observed by the original client)
  4. The client observes the event and subscribes to the subject "clientid" where id is the unique id received from the server
(For those who prefer the concrete, here are the implementations of this pattern in block-drop: server sideclient side, and shared code. You'll note that the client side code uses dynamic subscription, since the client's unique id cannot be known at compile time.)

Finishing the Invitation

With services based on unique ids setup for each player, it is now possible for server to target individual players in an invitation by accessing their unique ids. The relayed invitations are sent using the MessageBuilder as previously demonstrated. (Once again, here is the Block Drop implementation.)

Final Note

I hope this helps you to understand the power and flexibility that the Errai Bus provides. This is just one example out of the plethora of potential use cases that the Message Bus could fulfill. When you want the loose-coupling of CDI Events, but need a more fine-grained (or dynamic) control over recipients, Errai Messaging might be the right fit for the job.