- Description: A library to serve Server-Sent-Events from web applications based on Clack framework.
- Licence: Unlicense
- Author: Alexander Artemenko [email protected]
- Homepage: https://40ants.com/clack-sse/
- Bug tracker: https://github.com/40ants/clack-sse/issues
- Source control: GIT
- Depends on: lack-util-writer-stream, log4cl, log4cl-extras
This library allows you to add a route to the Clack application for serving Server-Side-Events.
SSE
is an alternative to the Websocket technique, allowing to push data from the backend to the frontend.
You can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:
(ql-dist:install-dist "http://dist.ultralisp.org/"
:prompt nil)
(ql:quickload :clack-sse)
Here is how a server-sent-events handler could be mounted into the Clack web application.
First, we need to define a handler which will write events to the OUTPUT-STREAM
:
(defun server-sent-events-handler (env output-stream)
(declare (ignore env))
(loop with counter = 0
repeat 100
do
(sleep 2)
;; Without sse-server module
;;(format output-stream "event:my-custom-event~%data:Hello World! ~d~%~%" (incf counter))
;; With sse-server module
(sse-server:send-event! output-stream
"my-custom-event"
(format nil "Hello World! ~d" (incf counter)))
(finish-output output-stream)))
Then, when we'll build our app, we will use clack-sse:serve-sse
function to create a Lack app and
mount
middleware to call it when browser makes a request to /events
route:
(defun start-server (&key (port 8080))
(let ((app (lack:builder
(:mount "/events"
(serve-sse 'server-sent-events-handler))
'index-page)))
(clack:clackup app
:port port
:use-thread nil)))
This example uses sse-server
ASDF
system to send event data in the correct format.
However, you can write directly to the OUTPUT-STREAM
if your data is simple enough.
You will find ready to use demo application in clack-sse-demo
ASDF
system:
(ql:quickload :clack-sse-demo)
(clack-sse-demo:start-server :port 8080)
package clack-sse
function clack-sse:default-on-connect
env
Accepts any connection and returns headers to prevent caching.
Here is what this function returns:
(list 200
(list :content-type "text/event-stream"
:cache-control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"))
function clack-sse:serve-sse
stream-writer &key (on-connect 'default-on-connect)
Returns a function suitable for accepting a connection from Clack framework and serving server-sent-events stream.
Argument STREAM-WRITER
should be a funcallable object accepting two arguments:
ENV
argument is the same plist as usual Clack applications receive.OUTPUT-STREAM
is a writable stream to write events to.
Additionally, you can provide ON-CONNECT
argument. If provided, it should be a function of one argument ENV
.
This function should return a list of two items: http code and a plist of HTTP
headers. You can use
it for authentication or a session initialization. Here is what as default for ON-CONNECT
argument function default-on-connect
is used.
See example application in the demo/app.lisp file.