SSE
1 Provided definitions
sse
make-sse
start-sse-tcp-port
send-new-event
2 Example of use
7.7

SSE

Oscar Alberto Quijano Xacur

 (require SSE) package: SSE

1 Provided definitions

The events stream is defined with a struct:

struct

(struct sse (sse-thread connection-threads messages-hash))

  sse-thread : thread?
  connection-threads : (listof thread?)
  messages-hash : hash?
  • sse-thread is the thread with the running SSE source

  • connection-threads is a list contaning the threads of the active connections

  • messages-hash is a hash table containing the messages with non-false #:id

procedure

(make-sse)  sse?

Creates a new event stream.

procedure

(start-sse-tcp-port port-no    
  a-sse    
  [max-allow-wait    
  reuse?    
  hostname])  procedure?
  port-no : positive-integer?
  a-sse : sse?
  max-allow-wait : exact-nonnegative-integer? = 4
  reuse? : boolean? = #f
  hostname : (or/c string? #f) = #f
Starts listening for connections on port port-no and uses a-sse to send events. It returns a procedure that stops listening once it is called. max-allow-wait, reuse? and hostname are as in tcp-listen.

As explained in this MDN web doc an event has one or more of four possible fields: id, event, data, retry. send-new-event can be used to send an event. It has keywords for the four possible fields.

procedure

(send-new-event a-sse    
  [#:data data    
  #:event event    
  #:id id    
  #:retry retry])  void?
  a-sse : sse?
  data : (or/c string? null?) = empty
  event : (or/c string? null?) = empty
  id : boolean? = #f
  retry : (or/c positive-integer? null?) = empty
If id is #t the message is send and it is added to the message-hash of a-sse. The actual id value sent is always a positive integer starting from one. It is automatically managed by the library. The messages added to the message-hash are sent to new connections. When the header Last-Event-ID is sent in a request only the messages with an id greater than that value are sent.

2 Example of use

The following code creates a page with a textarea that will be filled with the data field of events. The page can be accessed through the port 8080. The ECMAScript in the page connects to the port 8122 to get server sent events. Each time that an event is sent it is added to the textarea.

Save the following script in a file sse_test.rkt.

#lang racket
 
(require web-server/http/xexpr)
(require web-server/servlet-env)
 
(require SSE)
 
;; Page that connects to the server-sent events
(define (start-page req)
    (response/xexpr
        `(html
          (head
          (meta ([http-equiv "content-type"] [content "text/html; charset=utf-8"] ))
          (meta ([name "viewport"] [content "width=device-width"] ))
          (title "Events test"))
 
          (body
          (h1 "Welcome to the Events test")
          (textarea ([readonly ""]))
          (script
          "
          var evtSource = new EventSource(\"//localhost:8122\");
          var textArea = document.getElementsByTagName(\"textarea\")[0];
 
          evtSource.onmessage = function(e){
              textArea.value =  e.data + \"\\n\" + textArea.value ;
              console.log(e.data);
          }
          ")))))
 
(define a-sse (make-sse))
 
(define (start-all)
 
  ; start the SSE listener
  (define sse-stop (start-sse-tcp-port 8122 a-sse))
 
  ; starts the page servlet
  (define page-thread  (thread
                        (lambda ()
                          (serve/servlet start-page
                                         #:launch-browser? #f
                                         #:quit? #f
                                         #:servlet-path "/"
                                         #:port 8080))))
 
  ; return a function that stops the page servlet and the SSE listener
  (lambda ()
    (sse-stop)
    (kill-thread page-thread))
  )
 
 
(define stop-all (start-all))

Now go to the same folder where you saved the file and run the racket REPL. Then write

,enter "sse_test.rkt"

This starts the page servlet and the SSE server. Now, open your browser and go to the url localhost:8080. You are going to see a welcome message and an empty textarea. In order to add some text send a data only event as follows:

(send-new-event a-sse #:data "Hello World!")

At this point the text "Hello World!" appears in the text area.

Now open a new tab or window of your browser and go again to localhost:8080. Note that the message "Hello World!" does not appear in this window. This is because we used #:id with value #f (it is the default value). Let us now send one with #:id equal to #t.

(send-new-event a-sse #:data "Hello World! (again)" #:id #t)

At this point the two windows that you have open will show the messahe "Hello World! (again)". This would be the case even with #:id equal to #f. What makes the difference is that if you open now a new tab and connect to localhost:8080, that window will also show this message.