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
or write
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:
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.
- To be done
- - The current design does not use threads to perform tasks for
multiple hubs. This implies that the design scales rather
poorly for hosting many hubs with few users.
- 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.
- See also
- - http_upgrade_to_websocket/3 establishes a websocket from
the SWI-Prolog webserver.
- 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_member(?HubName, ?Id) is nondet
- True when Id is a member of the hub HubName.
- hub_send(+ClientId, +Message) is semidet
- Send message to the indicated ClientId. Fails silently if ClientId
does not exist.
- Arguments:
-
Message | - is either a single message (as accepted by
ws_send/2) or a list of such messages. |
- 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.
Re-exported predicates
The following predicates are exported from this file while their implementation is defined in imported modules or non-module files loaded by this module.
- 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.