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 definiton 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 occured 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>