Node-RED を簡易WEBサーバーにする


## はじめに

Node-RED を起動すると以下のようなメッセージが出ます。

    Nov 13:59:48 - [info] Settings file  : /home/amnt/cfgrjp/node-red/settings.js
    Nov 13:59:48 - [info] User directory : /home/amnt/.node-red
    Nov 13:59:48 - [info] Flows file : /home/amnt/.node-red/flows_vanadium.json
    Nov 13:59:48 - [info] Server now running at http://127.0.0.1:1880/

情報メッセージ[info]に、setting.js ファイルを読み取っていると出ています。このファイルでは Node-RED の Debug タブに出力されるメッセージの長さを規定する　 debugMaxLength　（デフォルト値 1000) などがあります。Node-RED を Web サーバーにするヒントがここに隠されています。以下の行がコメントアウトされていますね。

    //httpStatic: '/home/nol/node-red-dashboard/'

Node.js で express を利用している開発者も多いと思われますが、静的コンテンツを利用する場合には

	app.use(express.static(path.join(__dirname, 'public')));

などのように指定していることを覚えていると思います。Node-REDを動作させるアプリケーション red.js を開くと、次の行が見つかります。

	app.use("/",express.static(settings.httpStatic));

つまりは、Node-RED を簡易WEBサーバーにすることができるということです。

## Node-RED を簡易WEBサーバーにするための変更

Node-REDを簡易WEBサーバーにするには、httpStatic と httpAdminRoot の設定のコメントをはずします。ここでは、コンテンツディレクトリとして 'public'、Node-RED 本体は '/red' でアクセスできるように設定してみました。


	$ diff settings.js.original settings.js
	64c64
	<     //httpAdminRoot: '/admin',
	---
	>     httpAdminRoot: '/red',
	84c84
	<     //httpStatic: '/home/nol/node-red-dashboard/',
	---
	>     httpStatic: 'public',



public にしたのは、'npm install node-red' を実行したときに**すでに存在している**のですね。見てみると、まさに使ってくれといわんばかりの bootstrap / jquery などが存在します。

	$ ls public/vendor/
	ace  bootstrap  font-awesome  jquery  vendor.css  vendor.js
	
## 簡単に動作確認

まずは簡単に動作確認するため、簡単な html ファイルを public に放り込みます。

	<!DOCTYPE html>
	<html lang="en">
		<head>
			<meta charset=utf-8>
			<title>title</title>
		</head>
		<body>
			<h1>これはヘッダー</h1>
			<p>
				ここはパラグラフです
			</p>
		</body>
	</html>

Node-REDを起動し、確認してみます。

	$ node red.js
	
Browser は　1880 ポートを指定します。
	
![picture1.png](https://qiita-image-store.s3.amazonaws.com/0/74673/ee593db4-cf9d-ed7c-82d2-ce2244a002d8.png)

ついでに、/red も開いてみます。

![picture2.png](https://qiita-image-store.s3.amazonaws.com/0/74673/5cc43f76-ccf6-b009-554b-24da095f4058.png)


簡易WEBサーバーになっているようです。ここでおや？どこか　Bluemixなんかで見たことがある！と思われた方もいるかもしれません。実は、Bluemix の Node-Red テンプレートは最初からそのように工夫されていたのですね。Bluemixの場合、bluemix-setting.js ファイルが該当しますが、開くと以下のような行が見つかるはずです。


	// Move the admin UI
    httpAdminRoot: '/red',
    // Serve up the welcome page
    httpStatic: path.join(__dirname,"public"),


Bluemix の場合は、今回紹介しているものとはパラメータ内容が異なりますが、効果は同じです。

## これだけではつまらないので、少しカスタマイズ

せっかく Node-RED が動作しているので少しカスタマイズしてみます。せっかく bootstrap / jQuery が入っているのでそれを活用しない手はないですね。

Node-RED のフローとしては以下のフローを作成してみました。

![picture3.png](https://qiita-image-store.s3.amazonaws.com/0/74673/5e490887-cb0d-4e9c-db03-969a25f92ea7.png)

Twitterで 'Bluemix' というメッセージを検索し、検索結果の msg.tweet を msg.payload に変換した後、websocketでブラウザーに通知します（ブロードキャスト）。

index.html は Websocket からの通知を受けてメッセージを表示しています。

	<!DOCTYPE html>
	<html lang="en">
	<head>
		<meta charset="utf-8">
	    <!-- Bootstrap core CSS -->
	    <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
	</head>
	<body>
		<div class="container">	
			<H1> みんなのBluemixつぶやき </H1>
			<div id="twitter"> </div>
		</div>	
	
		<script src='vendor/vendor.js'></script>
		<script>
			var tweet;
			var tweets = [];
			var wsUri = "ws://vanadium:1880/ws/twitter";
			var ws = new WebSocket(wsUri);
			
			ws.onmessage = function(evt) {
				
				tweet = JSON.parse(evt.data);
				tweets.unshift({text: tweet.text, profile_image: tweet.user.profile_image_url, name: tweet.user.name});
				
				var tbl = '<table class="table table-striped">';
				for (var i in tweets) {
					tbl = tbl + '<tr>';
					tbl = tbl + '<td>' + tweets[i].name + ' <img src=' + tweets[i].profile_image + '>' + '</td>';
					tbl = tbl + '<td>' + tweets[i].text + '</td>';
					tbl = tbl + '</tr>';
	 			}
	 			tbl = tbl + '</table>';
				document.getElementById("twitter").innerHTML = tbl;
			};
		</script>
	</body>
	</html>

動作させると一応出てますね（メッセージを出すためにつぶやきましたが(笑)）。

![picture4.png](https://qiita-image-store.s3.amazonaws.com/0/74673/a56fa79e-b1c8-3886-46d8-33a187184d66.png)

## おまけ

今回の内容は [PaaS 勉強会](http://paas.connpass.com/)　の内容を少し加工しています。勉強会では、Twitterのメッセージはローカルで実行しましたが、Node-RED がリモートにあるので動かないユーザーがいました。そこで、次回への教訓として、今度は Node-RED 本体に任せようと思い、資料を修正しているのですが、どうせなので Qiita にも投稿しようかなと思ったしだいです。なお、今回がはじめての投稿です。今後ともよろしくお願いいたします。