そろそろ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
これでしばらくテストして上手く行けばリリースする。