@blog.justoneplanet.info

日々勉強

緊急地震速報 by Extensionのサーバーを書き直す

そろそろ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

これでしばらくテストして上手く行けばリリースする。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment