remote-jsでcommon Lispからjavascriptを送信


本記事はLisp Advent Calendar 2019 19日目の記事です。

遅刻しましたすいません!!!
前々から気になっていたremote-jsを使ってみました。もっと色々したかったのですが、時間の都合で動かしてみただけになってしまいました。

remote-js

remote-jsはcommon Lispからevalでブラウザに対してjavascriptのコードを送信することができます。

動かしてみた

  • ubuntu18.04
  • roswell 19.09.12.102
インストール
ros install remote-js
(ql:quickload :remote-js)
(defvar context (remote-js:make-context))
(remote-js:start context)

websocketサーバーをスタートします。

(with-open-file (stream (merge-pathnames #p"index.html" (user-homedir-pathname))
                        :direction :output
                        :if-exists :supersede
                        :if-does-not-exist :create)
  (write-string (remote-js:html context) stream))

htmlファイルを生成、remote-jsが接続するための最低限の中身を用意してくれます。
githubのissueにも上がっていますがデフォルトだとアドレスが0.0.0.0になっていてwindowsではうまく動かないため

(remote-js:make-context 
                    :address "127.0.0.1")

こんな感じでアドレスを指定してあげる必要があります。

index.html
<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"></head><body><script>window.RemoteJS = {};
var RemoteJS = window.RemoteJS;

RemoteJS.send = function(data) {
  RemoteJS.ws.send(data);
};

RemoteJS.connect = function() {
  var ws  = new WebSocket("ws://0.0.0.0:40000/");

  ws.onmessage = function(evt) {
    (1, eval)(evt.data);
  };

  ws.onopen = function() {
    RemoteJS.send('connected');
  };

  ws.onclose = function() {
    setTimeout(RemoteJS.connect, 1);
  };

  RemoteJS.ws = ws;
};

RemoteJS.connect();</script></body></html>

生成されたhtmlファイルはこんな感じになっています。

(remote-js:eval context "alert('hello!')")

このように文字列でjsのコードを送信するとindex.htmlを開いているブラウザ上でも

アラートが出ました。
他にもdocument.write()なども問題なく動作をします。

htmlのbodyに次のdivタグを追加して

<div id="text"></div>
(remote-js:eval context "document.getElementById('text').innerHTML='hello world!'")

を実行すると

こんな感じでhello world!が表示されました。

おわり

web系のlispプログラミングも調べれば調べるほど色々できて面白いですね。
今回動かすだけで終わってしまったのが残念なのでcaveman2と組み合わせてみたり色々試してみたいことはあるので何か活用してみたいと思います。

お付き合いいただきありがとうございました。