Common LispでZeroMQを試してみた。
使用環境は以下のとおり
以下を参考にquicklispをインストールする。
$ curl -O http://beta.quicklisp.org/quicklisp.lisp $ sbcl (load "quicklisp.lisp") (quicklisp-quickstart:install :path ".quicklisp/") (ql:add-to-init-file)
※ (quicklisp-quickstart:install :path ".quicklisp/") のパスで最後のスラッシュは省略不可
(ql:quickload :zeromq)
ここで以下のようなエラーがでる場合はzeromqのインストールができていないか、ld.so.confに問題がある。ld.so.confにzeromqをインストールしたディレクトリがはいってることを確認して、sudo ldconfig すればちゃんとロードされるはず。
debugger invoked on a LOAD-FOREIGN-LIBRARY-ERROR in thread #<THREAD "initial thread" RUNNING {10029990A3}>: Unable to load any of the alternatives: ("libzmq.so.0.0.0" "libzmq.so") Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [RETRY ] Try loading the foreign library again. 1: [USE-VALUE ] Use another library instead. 2: [TRY-RECOMPILING] Recompile package and try loading it again 3: [RETRY ] Retry loading FASL for #<CL-SOURCE-FILE "zeromq" "package">. 4: [ACCEPT ] Continue, treating loading FASL for #<CL-SOURCE-FILE "zeromq" "package"> as having been successful. 5: [ABORT ] Give up on "zeromq" 6: Exit debugger, returning to top level. (CFFI::FL-ERROR "Unable to load any of the alternatives:~% ~S" ("libzmq.so.0.0.0" "libzmq.so")) 0] 2
以下のようにしてライブラリのパスを設定してやっても回避はできるがおすすめしない。
(pushnew "/path/to/lib/" *foreign-library-directories*)
cl-zmq のサンプルコード参考に以下のようなエコーサーバを書いた。これをserver.lispに保存して、 sbcl --script server.lisp で実行。ちなみに、127.0.0.1:5555 の部分をlocalhost:5555のように書くとNo such deviceといわれる。 (参考 Why doesn't zeromq work on localhost? )
(load "~/.sbclrc") (ql:quickload :zeromq) (defun server () (zmq:with-context (ctx 1) (zmq:with-socket (socket ctx zmq:rep) (zmq:bind socket "tcp://127.0.0.1:5555") (loop (let ((query (make-instance 'zmq:msg))) (zmq:recv socket query) (let ((req-string (zmq:msg-data-as-string query))) (format t "Recieved message: '~A'~%" req-string) (zmq:send socket (make-instance 'zmq:msg :data req-string)) )))))) (server)
こちらも同様に以下をclient.lispに保存して、sbcl --script client.lispで実行。うまくいけばサーバ側からレスポンスが返ってくる。
(load "~/.sbclrc") (ql:quickload :zeromq) (defun client () (zmq:with-context (ctx 1) (zmq:with-socket (socket ctx zmq:req) (zmq:connect socket "tcp://127.0.0.1:5555") (loop (zmq:send socket (make-instance 'zmq:msg :data (read-line))) (let ((result (make-instance 'zmq:msg))) (zmq:recv socket result) (format t "Recieved message: '~A'~%" (zmq:msg-data-as-string result) )))))) (client)
Common Lisp(sbcl)でZeroMQを利用して、簡単なエコーサーバ/クライアントを実装した。
メモメモ
CL-USER> (sb-mop:class-slots (find-class 'sb-posix:stat)) (#<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::MODE> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::INO> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::DEV> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::NLINK> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::UID> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::GID> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::SIZE> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::ATIME> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::MTIME> #<SB-MOP:STANDARD-EFFECTIVE-SLOT-DEFINITION SB-POSIX::CTIME>)