14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

KIT DeveloperAdvent Calendar 2016

Day 13

HerokuでExpressとexpress-wsを使ってチャットアプリを動かすサンプル

Posted at

先日、Herokuで静的ファイルにNode.js経由 ( Express4.x系 ) でアクセスする時の注意点 という記事を書きました。

その記事で紹介した y-temp4/heroku-static-provider を元に、Expressとexpress-wsを使ったチャットアプリのサンプルを作ってみようと思います。

ソースコードはこちら y-temp4/express-ws-chat-sample

express-wsを入れる

まずはexpress-wsを入れます。

$ yarn add express-ws

package.jsonはこんな感じです。

package.json
{
  "name": "heroku-static-provider",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "basic-auth-connect": "^1.0.0",
    "compression": "^1.6.2",
    "express": "^4.14.0",
    "express-ws": "^2.0.0",
    "morgan": "^1.7.0",
    "serve-static": "^1.11.1"
  }
}

サーバーの実装

次に、サーバー側を実装します。

server.js
const express     = require('express');
const app         = express();
const expressWs   = require('express-ws')(app);
const morgan      = require('morgan');
const compression = require('compression');
const serveStatic = require('serve-static');
const basicAuth   = require('basic-auth-connect');

const user = process.env.USER;
const pass = process.env.PASS;

let connects = [];

app.set('port', process.env.PORT || 3000);

if (user && pass) {
  app.use(basicAuth(user, pass));
}

app.use(morgan('dev'));
app.use(compression());
app.use(serveStatic(`${__dirname}/public`));

app.ws('/', (ws, req) => {
  connects.push(ws);

  ws.on('message', message => {
    console.log('Received -', message);
    
    connects.forEach(socket => {
      socket.send(message);
    });
  });
  
  ws.on('close', () => {
    connects = connects.filter(conn => {
      return (conn === ws) ? false : true;
    });
  });
});

app.listen(app.get('port'), () => {
  console.log('Server listening on port %s', app.get('port'));
});

全員に送信したり、切断時の処理を行うために変数connectsにて接続状況を管理しています 1

クライアントの実装

public/client.js
(function() {
  var HOST = location.origin.replace(/^http/, 'ws');
  var ws = new WebSocket(HOST);
  
  var form = document.querySelector('.form');

  form.onsubmit = function() {
    var input = document.querySelector('.input'); 
    var text = input.value;
    ws.send(text);
    input.value = '';
    input.focus();
    return false;
  }
  
  ws.onmessage = function(msg) {
    var response = msg.data;
    var messageList = document.querySelector('.messages');
    var li = document.createElement('li');
    li.textContent = response;
    messageList.appendChild(li);
  }
}());

サーバー側もそうですが、メッセージを送受信するために最低限のことしか書いていません。

動作確認

まずはサーバーを起動して、localhost:3000にアクセスします。

$ node server.js

左側のブラウザで入力した文字列が右側でも表示できていることが確認できますね。

冒頭にも書きましたが、y-temp4/express-ws-chat-sampleからソースコードを参照できます。Herokuへのデプロイボタンも用意してあるので、実際にHerokuの環境で動かしてみたい方は試してみてください。

以上です。


  1. 参考:WebSokectライブラリの「ws」を使ってみた - .blog

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?