BluemixにNode.js+Express+Socket.ioで作ったチャットをホスティングするチュートリアル


ジーズアカデミーアドベントカレンダーということで学生さんも試せるチュートリアルを書いたつもりです。
> あと https://teratail.com/Bluemix にも登録してます

最近AzureにLINE Botを乗せて運用しようかと思ってたんですけど、思うようにいかずAzure側、LINE側どちらで詰まっているのか検証したいというのもありBluemixにLINE Botを乗せてみよう...って思ってたんですけど、ちょっとハマった(別の機会に書きます)ためチャットデモのホスティングにしたいと思います苦笑

完成品はこちらです。 チャットしましょう。

> https://n0bisuke-bot-test.mybluemix.net/

サブドメイン名がn0bisuke-bot-testになってるのがやろうとした爪痕ですね苦笑

## 環境

* macOS Sierra
* Node.js 7.2.0

## アプリを作る

まずは[Bluemix](www.ibm.com/developerworks/jp/bluemix/)に登録してアプリケーションを作ります。

* SDK for Node.jsを選択

![](https://i.gyazo.com/7a6bfe27520c85033790dfc04215d87c.png)

* アプリケーション名をつける

![](https://i.gyazo.com/bdb30c76cde817122cae89bf91b4ca57.png)

* アプリが立ち上がるのを待つ

![](https://i.gyazo.com/dde6ca0a82c284c4ea439d95494a648b.png)


アプリの表示で確認するとページが出来上がってるのが確認できます。

![](https://i.gyazo.com/382db70ef863030cad0a20949fd58bf9.png)


ここまで5分くらい

めちゃ簡単。

~~ただし、一番最初のBluemixに登録するフローがひたすらめんどくさいのでなんとかならないかなぁ(ﾁﾗﾁﾗ~~

## サンプルWebアプリをデプロイする準備

BluemixでアプリケーションをデプロイするのにはHerokuコマンドみたいなツールが必要になります。
BluemixコマンドとCFコマンドの二つを使えるようにしましょう。

![](https://i.gyazo.com/1f3f1ef3fcc0e563f53015649a78ad27.png)

### Bluemix CLIをローカルマシンにインストール

> http://clis.ng.bluemix.net/ui/home.html

![](https://i.gyazo.com/e225c51120fc0eff4da10992824bad75.png)

自分の環境に合わせてダウンロードしてPCにインストールします。僕はmacOS Sierraですが問題なく使えました。

インストールが完了したらターミナルで`bluemix`コマンドを叩きます。

![](https://i.gyazo.com/e8e8fa9cd2d4f3f83e43bbea9af4ce85.png)

これで`bluemixコマンド`が使えるようになりました。

### CFをローカルマシンにインストール

> https://github.com/cloudfoundry/cli/releases

![](https://i.gyazo.com/0795202c6b4acfd188969f54dd26768e.png)

bluemixコマンド同様です。環境に合わせてDL&インストールしましょう。

![](https://i.gyazo.com/9e3635973dc6f80916e77db9ad80dd2c.png)

これで`cfコマンド`が使えるようになります。

### スターターコードの内容確認
`スターター・コードをダウンロードし、パッケージを新規ディレクトリーに解凍して開発環境をセットアップします。`の箇所からzipファイルをダウンロードしましょう。zipファイルを解凍すると以下のようなファイル構成が確認できます。

![](https://i.gyazo.com/2cb05d15b979f8f2a9ea59f3c3f7a974.png)

試しに`public/index.html`を編集して、`hello world`の部分を好きな文字に変更します。今回は`こんにちは世界！`にしました。

![](https://i.gyazo.com/5a2ef87e32512730c1b0324574047b77.png)

まずはローカル環境で動作確認をしてみます。

```
npm i
node app
```

http://localhost:6001 にブラウザからアクセスします。

![](https://i.gyazo.com/087fc9c8ef3b8183fc57a322d9becbb9.png)

とりあえず手元での動作は確認できました。

## サンプルWebアプリをデプロイしてみる

### Bluemixに接続する

```
bluemix api https://api.ng.bluemix.net
```

と

```
cf login -u メールアドレス -o 組織名 -s スペース名
```

の二つのコマンドでターミナルのCLIツールをBluemixに接続します。

```
$ bluemix api https://api.ng.bluemix.net

'cf api https://api.ng.bluemix.net' を起動しています...

API エンドポイントを https://api.ng.bluemix.net に設定しています...
OK


API エンドポイント:   https://api.ng.bluemix.net (API バージョン: 2.54.0)
ログインしていません。 'bluemix login' を使用してログインしてください。
```

```
$ bluemix login -u xxxxxx@xxxxx -o "dotstudio" -s "akihabara"
'cf login -u sugawara@ryousuke.org -o dotstudio -s akihabara' を起動しています...

API エンドポイント: https://api.ng.bluemix.net

Password> (ここにBluemixアカウントのパスワードを入力)
認証中です...
OK

組織 dotstudio をターゲットにしました

スペース akihabara をターゲットにしました

API エンドポイント:   https://api.ng.bluemix.net (API バージョン: 2.54.0)
ユーザー:             xxxxxxxx@xxxxxxxx
組織:                 dotstudio
スペース:             akihabara
```

これで手元の環境がBluemixに接続されます。

### Bluemixにデプロイ

```
cf push アプリ名
```

でデプロイできます。

```
cf push "n0bisuke-bot-test"
```

![](https://i.gyazo.com/74cddb0a822467b3f3efc70d53c4d4ed.png)


アプリ名.mybluemix.netなどにアクセスして先ほどの`こんにちは世界！`の表示になってるか確認しましょう。

## チャットアプリケーションをデプロイしてみる

さて、あとは前回作った「[Node.js+Express+socket.ioでリアルタイムチャットを作ってWeb Appsに無料ホスティングする（yarnも試してみた）](http://qiita.com/n0bisuke/items/dfb588013838133f6045)」のソースコードを元に作ります。

> https://github.com/n0bisuke/express-socke.io-webapps

* public/index.htmlを以下に書き換え

フロント側コードです。

```
<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>

    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-3.1.1.slim.js"   integrity="sha256-5i/mQ300M779N2OVDrl16lbohwXNUdzL/R2aVUXyXWA="   crossorigin="anonymous"></script>
    <script>
        const socket = io();
        $('form').submit(() => {
            socket.emit('chat message', $('#m').val());
            $('#m').val('');
            return false;
        });
        socket.on('chat message', (msg) => {
            $('#messages').append($('<li>').text(msg));
        });
    </script>

  </body>
</html>
```

* app.jsを以下に書き換え

```
'use strict';

const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const cfenv = require('cfenv');
const appEnv = cfenv.getAppEnv();
const PORT = appEnv.port;

app.get(`/`, (req, res) => {
  res.sendFile(__dirname + '/public/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('chat message', (msg) => {
    console.log('message: ' + msg);
    io.emit('chat message', msg);
  });
});

http.listen(PORT, () => {
  console.log(`listening on *:${PORT}`);
});
```

ちなみに、この`appEnv.port`の部分がBluemixでの起動ポートの指定方法みたいです。

```
const cfenv = require('cfenv');
const appEnv = cfenv.getAppEnv();
const PORT = appEnv.port;
```

* socket.ioをインストール

```
npm i --save socket.io
```

* 最後にデプロイ

```
cf push "n0bisuke-bot-test"
```

![](https://i.gyazo.com/a821db3098745408acfee24befdb8ced.gif)

こんな感じの画面でチャットができるようになってれば完成です。

## おわりに

Bluemixは最初の登録が面倒ですが、そのあとは割と簡単にデプロイまでいけた感触です。

あと、管理画面のサイドバーのログタブからリアルタイムにログが見れるのが割と便利(Azure WebAppsだとNode.jsのconsole.logがデフォルトでうまく表示されないんですよね。)
![](https://i.gyazo.com/f89412f12ac11b37aa282e94de7756d6.gif)


ジーズアカデミーの学生さんもぜひ試してみてください！