websocket 使ってみた


概要

npm でダウンロードできる node のモジュール websocket を使って、コインチェックの websocket の API に接続し、ビットコインの価格をリアルタイムで取得してみた。

道具立て

websocket を Node で使うには websocket というライブラリを使う人が多いのでこれを使うことにした:

npm i -S websocket

接続先は、みんな大好きコインチェック。認証なしで使える Websocket のAPIがあるので使わせてもらう

  • ドキュメント: https://coincheck.com/ja/documents/exchange/api#websocket
  • エンドポイント: wss://ws-api.coincheck.com/
  • 使い方
    • 接続後、この文字列を送信: {type: "subscribe", channel: "btc_jpy-trades"}
    • 以下の形式の文字列データが次々とやってくる
[
  104749190, // ID
  "btc_jpy", // 取引ペア
  "783714.0", // レート
  "0.005", // 量
  "sell" // 方法
]

手順

プログラムの全体構造は、Client オブジェクトを作って、接続時に呼び出されるコールバックを登録した後に、実際に接続する、という形になる:

const Client = require('websocket').client;

const main = () => {
  const client = new Client();
  client.on('connect', onConnect);
  client.connect('wss://ws-api.coincheck.com/');
};

コールバックが呼び出される際には、Connection オブジェクトが渡されるので、send メソッドを呼び出して送信したり、メッセージ受信時のコールバックを登録したりできる:

const onConnect = (conn) => {
  console.log('connected');
  conn.on('message', onMessage);
  conn.send(JSON.stringify({ type: 'subscribe', channel: 'btc_jpy-trades' }));
};

メッセージ受信コールバックでは、メッセージオブジェクトが渡される。 utf8Data プロパティにアクセスすることで実際のデータにアクセスできるので、JSON.parse でオブジェクトに変換後、加工した:

const process = (raw) => {
  const obj = JSON.parse(raw);
  return ({
    time: +new Date(),
    type: obj[4], // sell or buy
    rate: parseFloat(obj[2]),
    vol: parseFloat(obj[3]),
  });
};

const onMessage = (msg) => {
  console.log(process(msg.utf8Data));
};

出力結果はこんな感じ:

{ time: 1533639554906, type: 'sell', rate: 783180, vol: 0.005 }
{ time: 1533639554970, type: 'sell', rate: 783179, vol: 0.005 }
{ time: 1533639555035, type: 'sell', rate: 783179, vol: 0.005 }
{ time: 1533639555870, type: 'buy', rate: 783462, vol: 0.0178 }
{ time: 1533639555935, type: 'buy', rate: 783466, vol: 0.0022 }
...(後略)

コード全体

const Client = require('websocket').client;

const process = (raw) => {
  const obj = JSON.parse(raw);
  return ({
    time: +new Date(),
    type: obj[4], // sell or buy
    rate: parseFloat(obj[2]),
    vol: parseFloat(obj[3]),
  });
};

const onMessage = (msg) => {
  console.log(process(msg.utf8Data));
};

const onConnect = (conn) => {
  console.log('connected');
  conn.on('message', onMessage);
  conn.send(JSON.stringify({ type: 'subscribe', channel: 'btc_jpy-trades' }));
};

const main = () => {
  const client = new Client();
  client.on('connect', onConnect);
  client.connect('wss://ws-api.coincheck.com/');
};

main();