The eventsource feature

Installing

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

Syntax

eventsource <source-name> [from <source-url>] [on <event-name> (as <encoding>) <commands> end] end

Description

Server Sent Events are a simple way for your web server to push information directly to your clients that is supported by all modern browsers. They provide real-time, uni-directional communication from your server to a browser. Server Sent Events cannot sent information back to your server. If you need two-way communication, consider implementing WebSockets instead.

SSE connections can require substantial work to set up and maintain. For example, browsers are supposed to reconnect to a failed SSE stream automatically, but their behavior differs. Hyperscript manages everything for you, and reconnects connections that have failed, so your code only has to handle incoming messages.

eventsource ChatUpdates from http://myserver.com/chat-updates

  on newMessage as json
    log it
  end

  on updateMessage as json
    log it
  end

end

About Event Names

The SSE specification requires that every event listener must declare a specific event name that it will listen to. There is no ability to designate a "catch all" handler for any unnamed events. This means that you will need to know exactly what event names are being sent, and will need to write specific event handlers for each one.

However, servers can also send SSE messages with no name attached to them. In this case use an on message handler to catch unnamed events.

Decoding Messages

You can specify two different ways to decode the message contents. If you include as string in the message handler declaration, then the contents of the message will be populated in the handler exactly as they were sent, as a string.

Instead, if you specify as json, then hyperscript will parse the message as a JSON formatted string. If the data is not valid JSON, then it will throw an error

Last, if you do not specify any encoding, then hyperscript will pass the original data through unmodified.

Exposing EventSource Events

The EventSource object defined in every browser exposes several of its own events related to its own connection state. It generates standard Javascript events for open, close, and error. Each of these is available to your the hyperscript code like any other message generated by the system. Here's an example of how to use them:

eventsource demo from http://server/demo

    on message as string
        put it into #div
    end

    on open
        log "connection opened."
    end

    on close
        log "connection closed."
    end

    on error
        log "handle error here..."
    end

end

The EventSource Variable

When you define an event source, it places a stub variable inside the current scope. This variable stores the raw EventSource object provided by the browser, tracks connection retries, and publishes two useful methods that you can use within hyperscript. (see below for an example)

You can also listen to events from this variable in other parts of your hyperscript code.


-- define the SSE EventSource
eventsource UpdateServer from http://server/updates
    on message
        log it
    end
end

-- elsewhere in your code, listen for the "cancelGoAway" message, then disconnect
on cancelGoAway from UpdateServer
    log "received cancel message from server"
    call UpdateServer.close()
end

Dynamic Server Connections

You may need to change the server URL that your EventSource is connected to. You can do this at any time calling the open(url) method on the EventSource variable. You can also initialize all of the handlers for an EventSource in your hyperscript application without connecting it to any server at all.

Calling the open() method repeatedly will close out any old connections and create a new connection on the updated URL.

eventsource DynamicServer
    on message as json
        log it
    end
end

-- somewhere else in your code
DynamicServer.open("test.com/test1.sse") -- creates a new connection to this URL

DynamicServer.open("test.com/test2.sse") -- automatically closes the first connection
DynamicServer.close()

DynamicServer.open("test.com/test3.sse") -- reconnects to a different endpoint.

Other Values Available To SSE Event Handlers

The following variables are populated within the event handler's scope when it is executed.

Example

Updating Records In Real-Time

<script type="text/hyperscript">
  eventsource recordUpdater from http://server-name/record-updater

      on message as json
          put it.name into #name
          put it.username into #username
          put it.email into #email
          log me
      end

  end
</script>

<div>
  <button script="on click call recordUpdater.open()">Connect</button>
  <button script="on click call recordUpdater.close()">Disconnect</button>
</div>

<h3>Real-Time Record</h3>
<div>Name: <span id="name">...</span></div>
<div>Username: <span id="username">...</span></div>
<div>Email: <span id="email"></span></div>