そろそろOAuth認証にしておかないとまずいので書きなおすことにした。
■環境構築
必要なパッケージのインストール等をする。
sudo yum -y install openssl-devel gcc-c++ git make git clone https://github.com/isaacs/nave.git ~/.nave ~/.nave/nave.sh install stable ~/.nave/nave.sh use stable echo "~/.nave/nave.sh use stable" >> ~/.bash_profile sudo curl https://npmjs.org/install.sh --insecure | sh npm -g install forever npm install twitter npm install websocket
以下のファイルを編集する。
vim /etc/security/limits.conf
以下の記述を加える。
* soft nofile 32768 * hard nofile 32768
■実装
以下のようにした。
const PORT = (process.argv[2])? process.argv[2] : 8080; const FOLLOWING_ID = 16052553; const CONSUMER_KEY = "CONSUMER_KEY"; const CONSUMER_SECRET = "CONSUMER_SECRET"; const TOKEN_KEY = "TOKEN_KEY"; const TOKEN_SECRET = "TOKEN_SECRET"; var util = require('util') , http = require('http') , twitter = require('twitter') , WebSocketServer = require('websocket').server ; util.puts('[' + new Date() + ']Listen ' + process.argv[2]); // build server var server = http.createServer(function(request, response) { util.puts('[' + new Date() + ']Received request for ' + request.url); response.writeHead(404); response.end(); }); server.listen(PORT, function() { util.puts('[' + new Date() + ']Server is listening on port ' + PORT); }); var wsServer = new WebSocketServer({ "httpServer" : server, "autoAcceptConnections" : true }); wsServer.on( 'connect', function(connection){ util.puts('[' + new Date() + ']Connection accepted.'); connection.sendUTF('{"status" : "accepted"}'); } ); setInterval(function () {wsServer.broadcastUTF("");}, 30 * 1000); // build twitter connection var twit = new twitter({ "consumer_key" : CONSUMER_KEY, "consumer_secret" : CONSUMER_SECRET, "access_token_key" : TOKEN_KEY, "access_token_secret" : TOKEN_SECRET }); twit.stream('statuses/filter', {"follow" : FOLLOWING_ID}, function(stream) { stream.on('data', function(data) { if (data['user']['id'] === FOLLOWING_ID) { delete data['source']; delete data['contributors']; delete data['entities']; delete data['favorited']; delete data['lang']; delete data['truncated']; delete data['in_reply_to_status_id']; delete data['in_reply_to_status_id_str']; delete data['in_reply_to_user_id']; delete data['in_reply_to_user_id_str']; delete data['in_reply_to_screen_name']; delete data['user']['name']; delete data['user']['screen_name']; delete data['user']['url']; delete data['user']['description']; delete data['user']['protected']; delete data['user']['followers_count']; delete data['user']['friends_count']; delete data['user']['listed_count']; delete data['user']['created_at']; delete data['user']['favourites_count']; delete data['user']['utc_offset']; delete data['user']['time_zone']; delete data['user']['geo_enabled']; delete data['user']['verified']; delete data['user']['statuses_count']; delete data['user']['lang']; delete data['user']['contributors_enabled']; delete data['user']['is_translator']; delete data['user']['profile_background_color']; delete data['user']['profile_background_image_url']; delete data['user']['profile_background_image_url_https']; delete data['user']['profile_background_tile']; delete data['user']['profile_image_url']; delete data['user']['profile_image_url_https']; delete data['user']['profile_link_color']; delete data['user']['profile_sidebar_border_color']; delete data['user']['profile_sidebar_fill_color']; delete data['user']['profile_text_color']; delete data['user']['profile_use_background_image']; delete data['user']['default_profile']; delete data['user']['default_profile_image']; delete data['user']['following']; delete data['user']['follow_request_sent']; delete data['user']['notifications']; util.puts('[' + new Date() + ']EEW ' + data); wsServer.broadcastUTF(JSON.stringify(data)); } }); stream.on('error' , function(err) { util.puts('[' + new Date() + ']Error::Stream' + err); }); }); setTimeout( function () { throw new Error('[' + new Date() + ']Error::for reboot'); }, 1000 * 60 * 60// 1 hour );
■起動
以前はnohupとか使ってたが、ちゃんとforeverを使うようにする。
ulimit -n 32768 forever start -a --spinSleepTime=10000 -w --watchDirectory=./ -l ~/.forever/eew80.log server.js 80 forever start -a --spinSleepTime=10000 -w --watchDirectory=./ -l ~/.forever/eew443.log server.js 443 forever start -a --spinSleepTime=10000 -w --watchDirectory=./ -l ~/.forever/eew8080.log server.js 8080
■サーバーの再起動
rebootするとforeverが止まるので起動スクリプトを書く。
/etc/rc.d/init.d/eewd
パスは適宜かえるとする。
/etc/init.d/functions NAME=eewd SOURCE_DIR=/var/www/hogehoge.com/eew SOURCE_FILE=server.js user=root pidfile=/root/.forever/pids/$NAME.pid logfile=/root/.forever/production.log forever_dir=/root/.nave/installed/0.8.17/bin node=/root/.nave/installed/0.8.17/bin/node forever=/root/.nave/installed/0.8.17/bin/forever sed=sed export PATH=$PATH:/root/.nave/installed/0.8.17/bin export NODE_PATH=$NODE_PATH:/root/.nave/installed/0.8.17/lib/node_modules start() { echo "Starting $NAME node instance: " if [ "$foreverid" == "" ]; then # Create the log and pid files, making sure that # the target use has access to them touch $logfile chown $user $logfile touch $pidfile chown $user $pidfile # Launch the application daemon --user=root \ $forever start -a -d --spinSleepTime=10000 -w --watchDirectory=$SOURCE_DIR -p $forever_dir --pidfile $pidfile -l $logfile $SOURCE_DIR/$SOURCE_FILE RETVAL=$? else echo "Instance already running" RETVAL=0 fi } stop() { echo -n "Shutting down $NAME node instance : " if [ "$foreverid" != "" ]; then $node $SOURCE_DIR/prepareForStop.js $forever stop -p $forever_dir $id else echo "Instance is not running"; fi RETVAL=$? } if [ -f $pidfile ]; then read pid < $pidfile else pid = "" fi if [ "$pid" != "" ]; then # Gnarly sed usage to obtain the foreverid. sed1="/$pid\]/p" sed2="s/.*\[\([0-9]\+\)\].*\s$pid\].*/\1/g" foreverid=`$forever list -p $forever_dir | $sed -n $sed1 | $sed $sed2` else foreverid="" fi case "$1" in start) start ;; stop) stop ;; status) status -p ${pidfile} ;; *) echo "Usage: {start|stop|status}" exit 1 ;; esac exit $RETVAL
これでしばらくテストして上手く行けばリリースする。