サーバ<>クライアント型でデータの可視化を行う。
少し難しくなるがコードの解説を詳しくやっていくと終わらないので割愛させて頂く。
実はsocket.io-client
はVue.js
から直接呼び出せるのでNode.js
サーバは省略できる。
しかし、将来的に中央のNode.js
サーバは24h稼働にして自動取引やデータ保存用としたいのでこの構成でスタートする。
余談:本来ならNode.js
の自前サーバ内からexpress
でVue.js
のHTTPサーバを兼任できるが、今回はコードをとにかく短く+サーバ軽量化もできるのでHTTPサーバはVue.jsの開発サーバ機能を使っていく。
まずはメインとなるindex.js
const bF = require('./bitFlyer.js')
const PORT = process.env.PORT || 7000;
const io = require('socket.io')(PORT)
const socket_bF_client = bF()
io.on('connection', function (socket) {
console.log(`a user connected[id:${socket.id}]`)
socket_bF_client.on("lightning_board_snapshot_FX_BTC_JPY", (message) => {
socket.emit("lightning_board_snapshot_FX_BTC_JPY",message)
})
})
このコードで注意するのはio
はサーバ用のオブジェクト。socket_bF_client
は板情報を受ける側のクライアント。更にsocket
となっているのはユーザ側のVue.js
が繋げてくる箇所。ここを「io.emit
」にしてしまうと送信データが何個も送信されるバグになる(クライアント別ではなくクライアントの数を全chに配信している?)
続いて1行目で現れるbitFlyer.js
は公式コードをパブリックchに限定した簡易バージョンが入っている
//モジュール化
module.exports = function () {
// Node.js (JavaScript)
const crypto = require("crypto");
const io = require("socket.io-client");
// 約定情報ではなく板情報(スナップショット)に設定
//const publicChannels = ["lightning_executions_FX_BTC_JPY"];
const publicChannels = ["lightning_board_snapshot_FX_BTC_JPY"];
const socket = io("https://io.lightstream.bitflyer.com", {
transports: ["websocket"] // specify explicitly
});
// connection handling
socket.on("connect", () => {
// subscribe to the Public Channels
for (const ch of publicChannels) {
socket.emit("subscribe", ch, err => {
if (err) {
console.error(ch, "Subscribe Error:", err);
return;
}
console.log(ch, "Subscribed.");
});
}
// 公式はここにプライベートチャンネルのコードがあったが削除
});
// 重要! index.jsで.onメソッドを受けるためにsocketごとreturnする
return socket;
}
publicChannels
の配列に入れる文字列(板情報を指定)は公式に表記があるので参照のこと。
key
やsecret
は必要ないので消去してある。合わせてプライベートチャンネル用のコードも削除。
socket
をreturn
してindex.js
で利用している点に注意。
コード的にエラーになりそうな箇所ではあるがなんの問題もなく動作している。
画面上は接続情報しか表示されないが裏で板情報を定期的に取得し続ける。
長くなるので必要な箇所のみ記述。将来的に外観を美しく揃えたいのでVuetify
を予めadd
してあるが今回のコードに影響はない。
<script> //参考
//スクリプトタグの下にインポート
import io from "socket.io-client";
export default { //参考
mounted
部。Vue.js
に関しての説明は他サイトを参照。
mounted() {
//今回はNode.jsサーバもローカルで動いている
this.socket = io("http://localhost:7000");
//Node.jsサーバに接続
this.socket.on("connect", () => {
//Node.jsサーバが板情報を受け取り次第Vue.js側にも同じメッセージをemitする
this.socket.on("lightning_board_snapshot_FX_BTC_JPY", message => {
// Vue.jsのdataに生のまま格納
this.board_data = message
});
});
},
テンプレート部。生で board_data
を表示する。
<template>
<v-container>
<v-row class="text-center">
{{board_data}}
</v-row>
</v-container>
</template>
Node.js
サーバー側を起動
node index.js
別のターミナルにてVue.js
の開発サーバで起動
npm run serve
ブラウザにて http://localhost:8080/ (環境によってポートは変わる)にて動作確認。
JSONがそのままテキストで表示されれば今回は完了だ。
このデータを加工し棒グラフのような表示にしていきたい。chart.js
の導入を考えているがこのあたりは実験も兼ねながらとなるが少しづつ記事にしていきたい。