hub.pl -- Manage a hub for websockets
This library manages a hub that consists of clients that are connected using a websocket. Messages arriving at any of the websockets are sent to the event queue of the hub. In addition, the hub provides a broadcast interface. A typical usage scenario for a hub is a chat server A scenario for realizing an chat server is:
- Create a new hub using hub_create/3.
- Create one or more threads that listen to Hub.queues.event from
the created hub. These threads can update the shared view of the
world. A message is a dict as returned by ws_receive/2 or a
hub control message. Currently, the following control messages
are defined:
- hub{error:Error, left:ClientId, reason:Reason}
- A client left us because of an I/O error. Reason is
read
orwrite
and Error is the Prolog I/O exception. - hub{joined:ClientId}
- A new client has joined the chatroom.
The
thread(s)
can talk to clients using two predicates:- hub_send/2 sends a message to a specific client
- hub_broadcast/2 sends a message to all clients of the hub.
A hub consists of (currenty) four message queues and a simple dynamic fact. Threads that are needed for the communication tasks are created on demand and die if no more work needs to be done.
- hub_create(+Name, -Hub, +Options) is det
- Create a new hub. Hub is a dict containing the following public
information:
- Hub.name
- The name of the hub (the Name argument)
- queues.event
- Message queue to which the hub
thread(s)
can listen.
After creating a hub, the application normally creates a thread that listens to Hub.queues.event and exposes some mechanisms to establish websockets and add them to the hub using hub_add/3.
- current_hub(?Name, ?Hub) is nondet
- True when there exists a hub Hub with Name.
- hub_add(+Hub, +WebSocket, ?Id) is det
- Add a WebSocket to the hub. Id is used to identify this user. It may be provided (as a ground term) or is generated as a UUID.
- hub_send(+ClientId, +Message) is semidet
- Send message to the indicated ClientId. Fails silently if ClientId does not exist.
- hub_broadcast(+Hub, +Message) is det
- hub_broadcast(+Hub, +Message, :Condition) is det
- Send Message to all websockets associated with Hub for which
call(Condition, Id)
succeeds. Note that this process is asynchronous: this predicate returns immediately after putting all requests in a broadcast queue. If a message cannot be delivered due to a network error, the hub is informed through io_error/3. - hub_broadcast(+Hub, +Message) is det
- hub_broadcast(+Hub, +Message, :Condition) is det
- Send Message to all websockets associated with Hub for which
call(Condition, Id)
succeeds. Note that this process is asynchronous: this predicate returns immediately after putting all requests in a broadcast queue. If a message cannot be delivered due to a network error, the hub is informed through io_error/3.