node.js覚書系メモ(標準ぽくないプラグイン編)

ながくなりそうなので分割

標準ぽいのは


1>おなじみのcron処理


npm install cron

var cronJob = require('cron').CronJob;
cronJob('0 */1 * * * *',function(){
    console.log('===You will see this message every day===');
});

ログローテトとか、一時期mail送るのに使ってたが


npm install mail

は直せずorz ちがうmail plugin使ったほうがいいのかも。。

やってるレベルは

ぐらいなんだけどな‥‥‥orz

プラグインの方はまだ試せてないです。
試して動いたら追記メモしよう。。



2> ログ出力クラスのオレオレ版(ローテートあり)

 node_modules/hogeLog.js
とか作っておく

var exec = require('child_process').exec;
var root_log = '/home/XXXX/node/hoge'

exports.log_rotate = function(){
    var today = new Date();
    var month = today.getMonth()+1;
    var day = today.getDate();
    var hours = today.getHours();
    var mm  = today.getMinutes();
    fileName = "log_" + month  + "_" + day + "_" + hours + "_"+mm + ".txt";

    console.log('You will see ' + fileName);

   //cp で指定位置にコピー退避した後 '' > sv_hoge.logで中身消すよ 
    var cmd = "cp "+root+"/sv_hoge.log "+ root + "/log/" + fileName +" && '' > "+ root +"/sv_hoge.log ";
    console.log(cmd);
    exec(cmd, function(err, stdout, stderr) {
         if(err) {
              console.log("err="+err);
              console.log("stdout="+stdout);
              console.log("stderr="+stderr);
         }
    });
}

//日付付きのコンソールログ出しておくよん
exports.log = function(str){
   var today = new Date();
   var today_str = today.toString();

   console.log(today_str + " , " + str);
}


node_modules に置いたのは
exports宣言しておくと require宣言で呼べるので

var dbg=require('hogeLog')

cronJob('0 0 */1 * * *',function(){
    console.log('===You will see this message every day===');
    dbg.log_rotate(); //追加するイメージ
});

な感じで使えると

まあlogrotateのライブラリはあるみたいなので

でもいいのですが、バージョン上がった時に直せないとかの問題が出てきたりします
<ココらへんが「オレオレFWがいい」主張論の原資だったりorz



3> async.waterfall

理解するまでに凄く悩んだ系


まず事前に


npm install async
でパッケージを入れた上で先に進むと。

var fs = require('fs')
, async = require('async')
, path = '/tmp/fsAsync.txt';

async.waterfall(
    [
    function(callback) {
        //ファイルを作成
        fs.writeFile(path, 'hello', function(error, file){
            callback(null);//B
        });
    },
    function(callback) {//B
        //ファイルポインタを生成
        fs.open(path, 'a', 0666, function (error, file){
            callback(null, file);//C(callback,file) => function<C>(file, callback) を想定(☆)
        });
    },
    function (file, callback) {//C
        //書き込み
        fs.write(file, '\nworld', null, 'utf-8', function () {
            callback(null, file);//D(callback,file) =>function<D>(file, callback) を想定(☆)
        });
    },
    function(file, callback) {//D
        //ファイルポインタをクローズ
        fs.close(file, function (error){
            callback(null);//E
        });
    },
    function(callback) {//E
        //ファイルの中身を読み込む
        fs.readFile(path, 'utf-8', function(error, data) {
            console.log(data);  //コンソールに出力
            callback(null);//後ろの関数定義がないので finish関数のほうが呼ばれる
        });
    }
    ], function (err) {//なんか途中でエラーでたよ or 終了だよ
		if(err) {
			// エラー時の処理
			console.log("error:" +err);
			var response = {status: 'error'};
			res.send(response);
			return;
		}
		var response = {status: 'success'};
		res.send(response);
    });

☆)の想定が理解できなかった。。
 だって逆じゃん! 引数としては

  • 呼ぶ方:Callbackが常に先頭
  • 呼ばれる方:Callbackが常に末尾

しかも callbackは省略不許可なイメージ*1

これみて
 async.waterfall な書き方もだめぽ => node.js駄目なう =>PHP/Perlマンセー
とか言われたんだよな。他の人に。。。
直感的ではないのは分かるんですけどね。。(汗




4> node proxy


npm install http-proxy
をまず事前に。


後実行は別プロセス & sudoで実行
/home/XXX/node/hoge/svProxy.sh

ROOT=/home/XXXX/node/hoge
nodefile=hogeProxy.js

cd $ROOT

/bin/kill -9 `/bin/ps aux | /bin/grep -e $nodefile| /usr/bin/awk '{print $2}'`

cd $ROOT
sudo /usr/local/bin/node $ROOT/$nodefile 2>&1 >> /dev/null&
#sudo /usr/local/bin/node $ROOT/$nodefile 2>&1 >> ./log/sv_proxy.log &
  • hogeProxy.js
var httpProxy = require('http-proxy');

var options = {
  router: {
'XXX.XXX.XXX.XXX/H':'XXX.XXX.XXX.XXX:1234',
'XXX.XXX.XXX.XXX/h':'XXX.XXX.XXX.XXX:1234',
'XXX.XXX.XXX.XXX':'XXX.XXX.XXX.XXX:4321' //IOS用とか
  }
};

// cat /etc/passwd 等で調べる(uid/gid)
httpProxy.createServer(options).listen(80, function() {
  try {
    process.setuid(500); // ここで変更後のuidを指定する
    console.log('New uid: ' + process.getuid());
    process.setgid(500); // ここで変更後のgidを指定する
    console.log('New gid: ' + process.getgid());
  }
  catch (err) {
    console.log('Failed to set gid: ' + err);
  }
});

80になぜって話は
SoftBankスマホのブラウザが80ポート系(あと多分443のHTTPS)ぐらいしか許可してないから。

あとrouterは

  • 上から解釈
  • ホスト名:ポート の形しか定義できない

の制限はあります。

あとnode-config と一緒に動かすと干渉するっぽい話も

セキュリティのためにuid変更し方がいいという記述を追加


5> sprintf


npm install sprintf

var sprintf = require('sprintf').sprintf;

sprintf("%02x%02x",A,B)

とか?
nodeだと下記の例みたいな日本語表示とかあまりやらん気もする‥‥‥
国際語対応とか考えたことないですね(汗
一応絵文字等は v7から対応はいってるそうなんですけど


6> pdfkit

試してみたけど結構重かった。。PDF出ること自体はすごいと思ったけど

フォントデータは

から取得して
 ./fonts/ipam.ttf
な感じで設置*2


npm install pdfkit
してから、express上経由だと下記な感じ

var PDFDocument = require('pdfkit');
app.get('/print', function(req, res){
  console.log(req.query); // for logging
  doc = new PDFDocument;
  
  
   doc.font('fonts/ipam.ttf')
   .fontSize(25)
   .text('あいうえお', 100, 100);

	//# Add another page
	doc.addPage()
	.fontSize(25)
	.text('Here is some vector graphics...', 100, 100);

	//# Draw a triangle
	doc.save()
	.moveTo(100, 150)
	.lineTo(100, 250)
 	.lineTo(200, 250)
	.fill("#FF3300");

	//# Apply some transforms and render an SVG path with the 'even-odd' fill rule
	doc.scale(0.6)
 	.translate(470, -380)
	.path('M 250,75 L 323,301 131,161 369,161 177,301 z')
	.fill('red', 'even-odd')
 	.restore();

	//# Add some text with annotations            
	doc.addPage()
	.fillColor("blue")
	.text('Here is a link!', 100, 100)
	//.underline(100, 100, 160, 27, color: "#0000FF")
	 .link(100, 100, 160, 27, 'http://google.com/');

	//# Write the PDF file to disk
	var path ='output.pdf'
	doc.write(path);
  
	res.writeHead(200, {'Content-Type': 'application/pdf'});
	res.download(path);
	//res.end('Hello World\n');
});



7> socket.io


8> websocket

*1:callbackで呼ばないと次のfunctionに遷移しない D=>Eとか

*2:標準フォントだと何になるんだろう?