SWI-Prolog HTTP support
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
    • Packages
      • SWI-Prolog HTTP support
        • Introduction
        • The HTTP client libraries
        • The HTTP server libraries
        • Transfer encodings
        • library(http/websocket): WebSocket support
        • library(http/hub): Manage a hub for websockets
          • hub_create/3
          • current_hub/2
          • hub_add/3
          • hub_member/2
          • hub_send/2
          • hub_broadcast/2
          • hub_broadcast/3
        • Supporting JSON
        • MIME support
        • Security
        • Tips and tricks
        • Status

6 library(http/hub): Manage a hub for websockets

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.

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:

  1. Create a new hub using hub_create/3.
  2. 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:

    • 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.

[det]hub_create(+Name, -Hub, +Options)
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.
[nondet]current_hub(?Name, ?Hub)
True when there exists a hub Hub with Name.
[det]hub_add(+Hub, +WebSocket, ?Id)
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.
[nondet]hub_member(?HubName, ?Id)
True when Id is a member of the hub HubName.
[semidet]hub_send(+ClientId, +Message)
Send message to the indicated ClientId. Fails silently if ClientId does not exist.
Message is either a single message (as accepted by ws_send/2) or a list of such messages.
[det]hub_broadcast(+Hub, +Message)
[det]hub_broadcast(+Hub, +Message, :Condition)
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.