LoginSignup
9
7

More than 5 years have passed since last update.

Node.js+Socket.io+StreamingAPIで実況支援Webアプリを作る

Last updated at Posted at 2017-02-15

目的

 自分の成果物について文書化することで、今後似た問題にぶつかった時の解決までの時間を早めることが目的です。

結論

 Twitter StreamingAPIとNode.js(socket.io)およびJavaScriptを用いた、ツイート速度(以下、TPS:Tweets Per Second)リアルタイム測定Webアプリケーションを開発しました。
 後述する"query.json"を追記・修正することで、どんなキーワードのTPSも測定可能です。今回は自分の趣味が高じ、プロ野球12球団のツイートに設定しています。
 動作は以下の通りです。

内容

 本アプリケーションの動作の流れは以下の図の通りです。(手書きで失礼)

処理解説

 図中で振った丸付き番号部分の処理について、以下に詳しく記載します。

No 動作 処理概要 処理説明
1 サーバ
(Node.js)
検索用キーワード読み込み サーバ上に置いた検索キーワード設定用JSON"query.json"を読み込みます。
2 サーバ
(Node.js+twit)
StreamingAPI接続 1の検索ワードでStreamingAPIに接続します。これでリアルタイムに野球関連のツイートを受信できます。
3 サーバ
(Node.js+socket.io)
ツイートをクライアントに送信 ツイート受信時に、そのツイートをクライアントに送信します。以降、4~6は受信の度に繰り返されます。
4 クライアント
(JavaScript)
応援チーム識別 "query.json"をクライアント側でも読み込み、「ツイートがどのチームを応援しているのか?(複数チーム認識可)」を識別します。
5 同上 TPSn算出 4で識別した応援チームにおけるツイート間の時間差から、TPSnを算出します。
6 同上 TPS移動平均算出 5の結果のままであるとTPSの分散が大きく、指標として参考になり難いです。よって任意の配列長で移動平均TPSを算出します。
7 同上 DOM反映 6で得られたTPSと、ツイート本文をDOMに反映します。

「5 TPSn算出」のコード

 本記事では「TPSnの算出方法」関数のみ紹介します。他処理部のコードは、機会があれば別の記事とします。

 計算過程の変数をグローバル変数にしたくなかったことや、引数を与えて処理をさせたかったため、クロージャ設計に挑戦しました。クロージャの動作については、以前、自身の学習のために記事を書きましたので、ご参考にどうぞ。

client.js
function calcTPSn() {
  const MAX_L = 10;
  var tps_t   = {};
  tps_t.tmp   = {}; 

  return function(team) {
    for (var i = 0; i < team.length; i++) {
      if (tps_t[team[i]] != undefined) {
        var now = new Date();
        tps_t[team[i]].push(1 / secondDistance(tps_t.tmp[team[i]], now)); //配列末尾に計測時間を追加
        if (tps_t[team[i]].length > MAX_L) { //配列長が一定以上になっていたら削除
          tps_t[team[i]].shift();
        }
        tps_t['tmp'][team[i]] = now; //現在時刻をtmpに更新
      } else {
        // TPS連想配列にキーがない(初めて計測するチーム)
        tps_t[team[i]]     = [];
        tps_t.tmp[team[i]] = new Date();
      }
    }
    console.log(tps_t);
    return tps_t;
  }

  // 時間差測定用関数
  function secondDistance(src, dst) {
    var deltaMillsecond = dst.getTime() - src.getTime();
    return deltaMillsecond / 1000;
  }
}

サーバディレクトリ構成

 参考に、サーバのディレクトリ構成を以下に示します。

root/
 ├ app.js
 ├ index.html
 ├ js/
 │ └ client.js
 ├ css/
 │ └ style.css
 ├ etc/
 │ └ query.json
 └ node_module
   ├ twit
   ├ socket.io
   └ ...

最後に

 「こういう機能が欲しい」という要望や、質問などありましたら、ぜひコメント欄へ記入をお願いします。自分のモチベーションが上がります。
 前回の記事がたくさんのいいねを頂き、嬉しかったです。

懸念点

  1. 初めてサーバサイドとフロントエンド両方をコーディングしたことで、「この処理はサーバorブラウザ、どちらで行うべきなのだろうか?」という視点を持てました。今回はクライアントに殆どの処理を任せてしまっていますが、定石ではどうなのでしょうか? その点考えてみたいです。
  2. 日本語のツイート以外も拾うため、MLBのDetroit "Tigers"やNFL(アメフト)のPhiladelphia "Eagles"も測定対象となっている。本家ドキュメントを参考に追記したい。(17/2/17追記)

展望

  1. TPSを各球団の線グラフで示して可視化するのは、より情報を見る側に伝えやすくなるうえ、時間経過を見る事もでき、有効だと考えています。
  2. 形態素解析によるHOTワードの表示機能は、以前作ったJava版(後述)では、満足いく出来にはなりませんでした。「今行われている6ゲームのうち、どこのどの選手が熱いか?」を分析できる機能を追加したい。
  3. Twitterで野球実況を見ていて、「話題になっているが、よく知らない選手」についてSTATSやキャリアなど検索するのが手間だなとよく感じます。これを解消するために、3.の形態素解析と合わせて、ツイートに含まれる選手名などを識別して、情報を検索して教えてくれる機能を追加したい。
  4. デザイン。CSS学習中です。

所見

 以前(約1年前)はJavaをやっており、以下のようなアプリケーションを作りました。今回やったことはこれのリメイクになります。

 ご覧のとおり、Javaの時の方が多機能でした。しかし、Javaが私の初のオブジェクト指向言語だったことや、後から機能を追加しすぎたために、メンテナンスが行えなくなりました。(どこを弄ってもエラーが出てしまい、なぜ正常に動いているかを把握できない状態でした)

 今回はその反省を生かして、最初に自分の決めた要件通りにまずシンプルに仕上げ、こうして公開しました。

参考文献

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7