Checkout Ring Adapter for Jetty 9

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.

(use 'ring.adapter.jetty9)
(run-jetty app {})

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.

(use 'ring.adapter.jetty9)
(run-jetty app {:websockets {"/loc" LocationTracker}})

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.

[ANN] Handlebars Clojure API

The ONLY real-world modern clojure templating system.
I just can’t believe that the clojure world doesn’t build web application with server-side template.
hiccup and enlive are neither **real-world**. So people tends to use single page architecture for a clojure backend. That’s PAINFUL.

Available on clojars [hbs "0.4.1"], code and docs on github. We have been using hbs on readwise.net for a long time.

第一个开关

过年回家路上无聊看了一些关于电子制作的书,知道了 Android 上的开发板 IOIO。另外认识了 Arduino 的程序,感觉要比想象中还要简单。本来担心还要学一门新的语言,看了之后发现完全是多虑。

在淘宝上找 IOIO 的时候正好发现了一整套元件。买回来以后看看可能价格是贵了,但是对我这样的新手来说,省去了自己找元件的麻烦。因为找元件实在是很容易让人退缩。

点亮 Arduino 基本上没什么问题。但是在 Archlinux 上访问 serial port 需要一些配置。首先要把用户加入 uucp 组确保可以访问 /dev/tty* 的设备。其次,需要给当前用户访问 /run/lock 的权限,否则 Arduino IDE 还是无法访问到 Arduino,这点在 Archlinux 的 Wiki 上有提及。

我这个开关电路太简单了就不详细说了,参考书是一本 Getting started with Arduino。据说这本书出第二版了,第一版上 Arduino 的版本不是 Uno,所以图片有一些出入,不过接口都没有变化。这第一个二极管开关的电路还是挺有成就感的,晚上我就可以让台灯什么的都退了休吧。

R/W Update#1: 更好的时间线

这周的工作,界面上能展示的不多。我们对时间线做了比较大的手术。

原先的时间线的工作机制,是以☐☐☐☐☐☐☐☐☐☐☐☐☐(此处省略200字)。这样的机制有两个明显的问题:

  1. 看过和没有看过的文章常常交错在一起,让人迷惘
  2. 一夜过后,时间线上出现很神奇的情况,文章的热度排列为「冷…热…冷…热…」

不仅是很多用户,我自己使用的过程中也感到很不方便。于是我们痛下决心,抄起键盘对时间线大刀阔斧一番。 一小时前上线的版本已经基本解决了上面提到的问题。如若问题依旧,请参考题图。

还有可以提一句,用户名旁边显示的数字是你的 Karma。目前 Karma 可以通过评论和评论被投票获得。

还有什么比工程师写得产品博客更平淡的,而且他还要一边 test on production。

对对对,我们的工程师 debugger87 昨天回家结婚,顺便过年了,我们祝他新婚愉快。