% This LaTeX document was generated using the LaTeX backend of PlDoc, % The SWI-Prolog documentation system \section{library(http/hub): Manage a hub for websockets} \label{sec:hub} \begin{tags} \tag{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. \end{tags} 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 \textit{event} queue of the hub. In addition, the hub provides a \textit{broadcast} interface. A typical usage scenario for a hub is a \textit{chat server} A scenario for realizing an chat server is: \begin{enumerate} \item Create a new hub using \predref{hub_create}{3}. \item 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 \predref{ws_receive}{2} or a hub control message. Currently, the following control messages are defined: \begin{description} \dictitem{hub}{\key{error}:\arg{Error}, \key{left}:\arg{ClientId}, \key{reason}:\arg{Reason}}A client left us because of an I/O error. \arg{Reason} is \const{read} or \const{write} and \arg{Error} is the Prolog I/O exception.\dictitem{hub}{\key{joined}:\arg{ClientId}}A new client has joined the chatroom. \end{description} The \verb$thread(s)$ can talk to clients using two predicates: \begin{itemize} \item \predref{hub_send}{2} sends a message to a specific client \item \predref{hub_broadcast}{2} sends a message to all clients of the hub. \end{itemize} \end{enumerate} 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.\vspace{0.7cm} \begin{description} \predicate[det]{hub_create}{3}{+Name, -Hub, +Options} Create a new hub. \arg{Hub} is a dict containing the following public information: \begin{description} \infixtermitem{\Sdot}{\arg{Hub}}{\term{name}{}} The name of the hub (the \arg{Name} argument) \infixtermitem{\Sdot}{\term{queues}{}}{\term{event}{}} Message queue to which the hub \verb$thread(s)$ can listen. \end{description} After creating a hub, the application normally creates a thread that listens to \arg{Hub}.queues.event and exposes some mechanisms to establish websockets and add them to the hub using \predref{hub_add}{3}. \begin{tags} \tag{See also} \predref{http_upgrade_to_websocket}{3} establishes a websocket from the SWI-Prolog webserver. \end{tags} \predicate[nondet]{current_hub}{2}{?Name, ?Hub} True when there exists a hub \arg{Hub} with \arg{Name}. \predicate[det]{hub_add}{3}{+Hub, +WebSocket, ?Id} Add a \arg{WebSocket} to the hub. \arg{Id} is used to identify this user. It may be provided (as a ground term) or is generated as a UUID. \predicate[nondet]{hub_member}{2}{?HubName, ?Id} True when \arg{Id} is a member of the hub \arg{HubName}. \predicate[semidet]{hub_send}{2}{+ClientId, +Message} Send message to the indicated \arg{ClientId}. Fails silently if \arg{ClientId} does not exist. \begin{arguments} \arg{Message} & is either a single message (as accepted by \predref{ws_send}{2}) or a list of such messages. \\ \end{arguments} \predicate[det]{hub_broadcast}{2}{+Hub, +Message} \nodescription \predicate[det]{hub_broadcast}{3}{+Hub, +Message, :Condition} Send \arg{Message} to all websockets associated with \arg{Hub} for which \verb$call(Condition, Id)$ succeeds. Note that this process is \textit{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 \predref{io_error}{3}. \end{description}