小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


node.js + socket.ioでキーワードにマッチしたツイートを眺めるプログラム作ったよ。(技術解説編)

2012.03.18追記

以下の記事は古くなっているため、最新版はこちらを参照してください。

はじめに

先日、node.js + socket.ioを使って、指定したキーワードに関連するツイートをTwitterから検索してきて、画面に表示していくプログラムを作ってみました。

このエントリでは、このプログラムの作り方とdotcloudにアップロードして動かすまでの手順を書いてみたいと思います。

はじめてのNode.js -サーバーサイドJavaScriptでWebアプリを開発する-
松島 浩道
ソフトバンククリエイティブ
売り上げランキング: 21,749

ソフトウェアのバージョン
  • Mac OS X 10.6.7
  • socket.io@0.6.3
  • twitter-node@0.0.2
  • express@2.3.11
  • ejs@0.4.3
事前準備

1. node.jsをインストールします。

wget http://nodejs.org/dist/node-v0.4.2.tar.gz
tar zxvf node-v0.4.2.tar.gz
cd node-v0.4.2
./configure
make
sudo make install
node -v
>v0.4.2

2. npmをインストールします。

sudo curl http://npmjs.org/install.sh | sudo sh

3. expressをグローバルインストールします。

sudo npm install express -g
node.js + socket.ioでキーワードにマッチしたツイートを眺めるプログラムをつくるまで

1. 作業用のディレクトリを作成します。

mkdir work
cd work/

2. expressコマンドでアプリケーションのひな形をつくります。テンプレートにejsを選択して、NodeTwitterという名前でフォルダを作成します。

express -t ejs NodeTwitter
cd NodeTwitter/

3. 必要なライブラリをローカルインストールします。
socket.ioは、WebSocketによるリアルタイム通信を提供するライブラリです。最新版は0.7xだけどそれをいれると動かないので、わざとバージョンを指定してインストールします。

sudo npm install socket.io@0.6.3
>socket.io@0.6.3 ./node_modules/socket.io

twitter-nodeは、Twitter Streaming APIを使ってツイートを検索するライブラリです。

sudo npm install twitter-node
>twitter-node@0.0.2 ./node_modules/twitter-node

Webアプリケーションのためのフレームワークexpressとテンプレートエンジンのejsを一緒にインストールします。

sudo npm install express ejs
>ejs@0.4.3 ./node_modules/ejs 
>express@2.3.11 ./node_modules/express 

つづいて、自動生成されたコードを編集していきます。

app.js

注意:+記号は追加したコード行です。
はじめにsocket.ioとtwitter-nodeをrequire関数で読み込みます。

var express = require('express');

var app = module.exports = express.createServer();
+var io = require('socket.io');
+var TwitterNode = require('twitter-node').TwitterNode;

最初にリクエストを受け付ける部分が//Routesと書かれた部分です。以下のコードはデフォルトのキーワードを"AKB48"で初期化して画面に表示させているだけです。

// Routes
var keyword = "AKB48";
app.get('/', function(req, res){
  res.render('index', {
    keyword: keyword
  });
});

ボタンが押された場合の処理は、以下のようにします。new TwitterNodeのところではTwitterアカウントの設定を行っています。twitter.addListenerでは誰かのツイートが見つかったときの処理を書いています。socket.ioのbroadcast関数を使って、すべてのクライアントにアカウント名とツイートを送信します。

app.post('/', function(req, res){
  // リクエストからキーワードを取得する
  if (req.body.keyword) {
    console.log('検索キーワード::' + req.body.keyword);
    keyword = req.body.keyword;
  }
  res.render('index', {
    keyword: keyword
  });

  // websocketの生成
  var socket = io.listen(app);
  // twitterのアカウント設定
  var twitter = new TwitterNode({
    user: 'ユーザID',
    password: 'パスワード',
    track: [keyword] // 検索するキーワード
  });
  
  // 誰かのツイートが見つかったときの処理
  twitter
    .addListener('tweet', function(tweet) {
      // アカウント名::ツイート内容をwebsocketで繋がっているクライアントに送信する
      socket.broadcast('@' + tweet.user.screen_name + '::<br>' + tweet.text);
    })
    .stream();  
});

dotcloudは8080ポートで動作するので、ポート番号を8080に変更します。

-app.listen(3000);
+app.listen(8080);
index.ejs

中のコードを削除し、空ファイルにします。

layout.ejs

websocketでサーバからメッセージを受信すると、socket.on('message'のイベントが発生します。この処理では、<li>タグをjQueryのprependToタグで先頭に挿入していきます。

    <script>
      var socket = new io.Socket();
      socket.connect();
      // メッセージを受信したら<li>タグを追加していく。
      socket.on('message', function(t) {
        $('<div></div>')
          .html('<li>' + t + '</li>')
          .prependTo('#tweets');
      });
    </script>

全体的にはこんな感じです。

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Twitter × Node.js feat. socket.io</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = new io.Socket();
      socket.connect();
      // メッセージを受信したら<li>タグを追加していく。
      socket.on('message', function(t) {
        $('<div></div>')
          .html('<li>' + t + '</li>')
          .prependTo('#tweets');
      });
    </script>
  </head>
  <body>
    <h1>Twitter × Node.js feat. socket.io</h1>
    <form id="frm" name="frm" method="POST" action="/">
    <input type="text" id="keyword" name="keyword" value="<%=keyword %>">
    に関する<input type="submit" id="search" name="search" value="ツイートを眺める">
    </form>
    <ul>
    <div id="tweets"></div>
    </ul>
  </body>
</html>
style.css

スタイルシートは見た目を良くするためpaddingの調整と角丸で表示するようなコードを追加します。

li {
  padding: 5px;
  margin-bottom: 7px;
  color: #FFF;
  background-color: #0593e2;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}
dotcloudにデプロイする

1. dotcloud_build.ymlという名前で以下のファイルをwork直下に配置します。

nodetwitter:
  requirements:
    - ejs
    - express
    - socket.io@0.6.3
    - twitter-node

2. supervisord.confという名前で以下のファイルをwork直下に配置します。

command = node app.js
directory = /home/dotcloud/current/NodeTwitter

3. dotcloud上にnodetwitterという名前でアプリケーションをつくります。
注意:実際にdotcloudにデプロイする場合はアプリケーション名を変更してください。

dotcloud create nodetwitter

4. アプリケーションをデプロイする

dotcloud deploy -t nodejs nodetwitter.www

5. クラウド上にアップロードする

dotcloud push nodetwitter.www .

これで完了です。以下のURLでデモアプリが動いています。