cavemanでwebsocket-driverを読み込んで、defrouteにwebsocket-driver:make-serverを入れるとよい。
前提
caveman2:make-project
でひな形を作成している。
(ql:quickload :caveman2) (caveman2:make-project #P"/path/to/myapp/" :author "<Your full name>")
システムにwebsocket-driverとswankを追加する
asdファイルのdefsystemに記載されている:depends-onに:websocket-driver
と:swank
を追加しておく。
websocketのルートを書く
websocket-driverのサンプルを動かすならこんな感じになる。
(defroute "/echo" () (format t "env: ~a~%" (request-env *request*)) (let ((ws (make-server (request-env *request*)))) (on :message ws (lambda (message) (format t "~a~%" message) (send ws message))) (on :open ws (lambda () (format t "Connected.~%"))) (on :error ws (lambda (error) (format t "Got an error: ~S~%" error))) (on :close ws (lambda (code reason) (format t "Closed because '~A' (Code=~A)~%" reason code))) (lambda (responder) (declare (ignore responder)) (start-connection ws))))
Swankサーバーの起動
asdファイルのdefsystemにある:componentsの:module “src"に(:file "swank")
を追加して、
以下の内容のsrc/swank.lisp
を作成する。
(in-package :cl-user) (defpackage no-name-server.swank (:use :cl :swank)) (in-package :no-name-server.swank) (swank:create-server :port 4005)
ポート番号は環境変数から取得するように書いた方がいいと思ってる。
参考: The Common Lisp Cookbook - Interfacing with your OSのmy-getenv
cavemanの起動
起動するときはclackupを使う。(ros install clack
)
APP_ENV=development clackup --server :woo --port 5000 app.lisp
caveman2:make-project
でパスの通っていない場所にひな形を作成した場合は
ros tap tap path-to.asd
でシステムにパスを通しておく必要がある。(ros install t-sin/ros-tap
)
slime-connectで接続
Slimeが設定されたEmacsで M-x slime-connect
を実行すると接続先IPとポートを聞いてくるので入力すると、
上記cavemanの実行している環境にREPLで入れる。
クライアント(JS)の実装
クライアント側はサンプルそのまま。
var ws = null; function connect() { ws = new WebSocket("ws://localhost:5000/echo"); ws.onmessage = function(evt) { console.log(evt.data); }; } function send(message) { ws.send(message) }
その他
cavemanでenvを取り出す方法がわからなくて悩んで探して (request-env *request*)
にたどり着いたので記録。
broadcastするにはwsを保持して全てにsendかな。
認証するなら以下の記事がわかりやすい。
以下の3種類が取り上げられていた。
- CookieまたはToken
- URLにパラメータを含める
- プロキシのログに残ったりしてちょっと怖いよね
- ユーザー毎に30秒だけ有効なURLを生成する
- Slack
- Real Time Messaging API | Slack
- このページ、各イベントの一覧とそのドキュメントへのリンクにもなっているのでわかりやすい