@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

Vue.jsからCommon Lispの関数をjsonrpcで呼ぶ

深町さんのポケットチェンジでの活躍を見て、私も試してみたくなった。

www.slideshare.net

最近は Vue.js で遊んでいるので、そこからjsonrpcでCommon Lispの関数を呼んでみた。

Common Lisp側の準備

Quciklispの更新

ros run --eval "(progn (ql:update-client) (ql:update-all-dists) (exit))"

これを忘れていてClackが古く、hunchentootの起動時にエラーが出ていた。

json-rpcのサーバーを用意

github.com

READMEに従いサーバーを用意する。

(ql:quickload :jsonrpc)
(defvar *server* (jsonrpc:make-server))
(jsonrpc:expose *server* "sum" (lambda (args)
                                 (format t "args: ~a~%" args)
                                 (reduce #'+ args)))

(jsonrpc:server-listen *server* :port 8787 :mode :websocket)
  • サーバーの起動
% ros -l server.lisp run
To load "jsonrpc":
  Load 1 ASDF system:
    jsonrpc
; Loading "jsonrpc"

(略)

[package jsonrpc]
Hunchentoot server is going to start.
Listening on localhost:8787.

Vue.js側の準備

github.com

JS側はこれを使った。

npm i -S jsonrpc-websocket-client

こちらもREADMEに従った内容を.vueに記述。

  • Jsonrpc.vue
<template>
  <div>
    <a @click="jsonrpc">RPC!!!</a>
    <div>Result: {{result}}</div>
  </div>
</template>

<script>
import Client from 'jsonrpc-websocket-client'

export default {
  data () {
    return {
      result: ''
    }
  },
  mounted: function(){
  },
  methods: {
    jsonrpc: function(){
      var view = this;
      async function main () {
        const client = new Client('ws://localhost:8787')
          console.log(client.status)
          // → closed
          await client.open()
          console.log(client.status)
          // → open
          view.result = await client.call('sum', [1, 2, 3])
          console.log(view.result)
          await client.close()
      }
      // Run the main function and prints any errors.
      main().catch(error => {
        console.error(error)
        view.result = error
      })
    }
  }
}
</script>

<style lang="less" scoped>
a {
  cursor: pointer;
}
</style>

実行イメージ

RPC!!! を押すとResultの横が6になる。

f:id:peccu:20170515143019p:plain

はまったところ

  • 依存するパッケージが古いことに気づかなかった
    • (ql:update-all-dists)していなかったし、ローカルにgit cloneしたClackも存在していた
  • json-rpcのtransport層の理解不足
    • webpackとhttpが混ざっていて、深町さんのjsonrpcでwebpackを選択しつつ、JS側はhttpを利用してうまくいかないと悩んでいた。

疑問

jsonrpcってCORSみたいな仕組みはどこで用意するんだろうか