The socket feature

Installing

Note: if you want the socket feature, you must either use the "Whole 9 Yards" release of hyperscript, or include the /dist/socket.js file.

Syntax

  socket <socket-name> <socket-url> [with timeout <time expr>]
    [on message [as json] <command-list>]

Description

Web Sockets provide a mechanism for two-way communication between a browser client and a server. Hyperscript provides a simple way to create them, as well as a simple Remote Procedure Call (RPC) mechanism layered on top of them.

Here is a simple web socket declaration in hyperscript:

socket MySocket ws://myserver.com/example
  on message as json
    log message
end

This socket will log all messages that it receives as a parsed JSON object.

You can send messages to the socket by using the normal send command:

    send myMessage(foo: "bar", doh: 42) to MySocket

RPC

Hyperscript provides a simple RPC mechanism layered on top of websockets. Given the socket definition above, you can make the following call in hyperscript:

<button
  _="on click call MySocket.rpc.increment(41) then put the result into me"
>
  Get the answer...
</button>

This will end up turning into a message that is send to the server via the socket, with the following format:

{
  "iid": "185795d2-84ca-11eb-8dcd-0242ac130003",
  "function": "increment",
  "args": [41]
}

The fields here are

The server can then invoke the method however it sees fit. It can then respond asynchronously with a response message of the following format:

{ "iid": "185795d2-84ca-11eb-8dcd-0242ac130003", "return": 42 }

The invocation id must match the original invocation id sent by the client. If an exception occurred this can be sent like so:

{
  "iid": "185795d2-84ca-11eb-8dcd-0242ac130003",
  "throw": "An error occurred when calculating the answer..."
}

Note that, to the caller in hyperscript, this will look synchronous thanks to the async-transparency of the hyperscript runtime.

If you wish to modify the default RPC timeout set for the socket, you can use a few different forms:

<!-- a 5 second timeout -->
<button
  _="on click call MySocket.rpc.timeout(5000).increment(41) then put the result into me"
>
  Get the answer...
</button>

<!-- no timeout -->
<button
  _="on click call MySocket.rpc.noTimeout.increment(41) then put the result into me"
>
  Get the answer...
</button>