- ANN tags:
- clojure
- jetty
- web
- websocket published: true comments: true
The Clojure world has been using Jetty 7 for quite a long time because it's supported by the Ring development team. However, Jetty 9 brings us exciting features like WebSocket and SPDY. In order to use websocket in my Clojure web application, I built this adapter last weekend.
[info.sunng/ring-jetty9-adapter "0.1.0"]
The API for Clojure is still consistent with the one for jetty 7.
[cc lang="clojure"]
(use 'ring.adapter.jetty9)
(run-jetty app {})
[/cc]
Options supported in jetty 9 are almost same as jetty 7 except the configurator is dropped. And a new "WebSockets" option is added. Accepting a map of context path and websocket class, it enables websocket protocol in your web application.
[cc lang="clojure"]
(use 'ring.adapter.jetty9)
(run-jetty app {:websockets {"/loc" LocationTracker}})
[/cc]
Due to the lack of WebSocket API standards, I don't spend time on the WebSocket abstraction. Just use Jetty's internal API for websocket. Here is a typical implementation of websocket listener.
;; sample code
(ns xxx.ws.location
(:gen-class
:name xxx.LocationTracker
:init init
:state state
:extends org.eclipse.jetty.websocket.api.WebSocketAdapter
:prefix ws-
:exposes-methods {onWebSocketConnect superOnWebSocketConnect})
(:require [clojure.data.json :as json]
[clojure.tools.logging :as logging]
[monger.collection :as mc])
(:import (org.eclipse.jetty.websocket.api WebSocketAdapter)
(java.util UUID)))
(defn ws-init []
[[] {:client-id (str (UUID/randomUUID))}])
(defn ws-onWebSocketConnect [this session]
(.superOnWebSocketConnect this session)
(logging/warn "new connection: " (get-client-id this))
(defn ws-onWebSocketText [this message]
(let [msg (json/read-json message)]
(case (:type msg)
...)))
(defn ws-onWebSocketClose [this status reason]
(logging/debug "close socket"))
Since Jetty will create new instance of adapter for each connection, it requires heavy usage of "gen-class" . Remember to add the namespace to AOT compilation. Detailed Jetty API spec can be found here.
And also find the project is here.