By U Zensen.

欲しいものはプログラミングで自分で作る。

node.jsとexpressを使ってルーム機能のあるリアルタイムチャットを作る!!

2016 / 10 / 12
JavaScript
161013_title

はじめに!!

どうも!node.jsにはまっているぴーすけです!

僕の作りたいゲームに必要そうなnode.jsを使うリアルタイム通信を絶賛勉強中です。

前回、今更だけどnode.jsのexpressでリアルタイムチャットを作る!!で基本的なことを学んだので、今回はその応用として、ルーム機能のあるリアルタイムチャット機能を作ります。

スポンサードリンク

前提

今回は前回の今更だけどnode.jsのexpressでリアルタイムチャットを作る!!で作ったファイルを少し修正しただけなので、必要なもののインストール方法やその他の必要なファイルの記述はそちらを参考にしてください!

参考URLで解説をしていますが、今回作るチャットのディレクトリ構成は以下のようになっています。

161012_1

chat.jsにはサーバーサイドの処理を書き、index.htmlにはクライアントサイドの処理を書いています。

サーバーサイドの記述

以下の記述になります。

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var POST = 3000;

//ルートディレクトリにアクセスした時に動く処理
app.get('/', function(req, res) {
  //index.htmlにリダイレクトする
  res.sendFile(__dirname + '/index.html');
});

//socket.ioに接続された時に動く処理
io.on('connection', function(socket) {
  //接続時に振られた一意のIDをコンソールに表示
  console.log('%s さんが接続しました。', socket.id);

  //デフォルトのチャンネル
  var channel = 'channel-a';

  //接続時に自分以外の全員にIDを表示
  socket.broadcast.emit('message', socket.id + 'さんが入室しました!', 'system');

  //Roomを初期化するらしい
  socket.join(channel);

  //messageイベントで動く
  //同じチャンネルの人にメッセージを送る
  socket.on('message', function(msj) {
    io.sockets.in(channel).emit('message', msj, socket.id);
  });

  //接続が切れた時に動く
  //接続が切れたIDを全員に表示
  socket.on('disconnect', function(e) {
    console.log('%s さんが退室しました。', socket.id);
  });

  //チャンネルを変えた時に動く
  //今いるチャンネルを出て、選択されたチャンネルに移動する
  socket.on('change channel', function(newChannel) {
    socket.leave(channel); //チャンネルを去る
    socket.join(newChannel); //選択された新しいチャンネルのルームに入る
    channel = newChannel; //今いるチャンネルを保存
    socket.emit('change channel', newChannel); //チャンネルを変えたこと自分に送信
  });
});

//接続待ち状態になる
http.listen(POST, function() {
  console.log('接続開始:', POST);
});

クライアントサイドでチャンネルを変更できるようにするので、デフォルトではチャンネルAには入っているようにして、チャンネルが変更されたら部屋を出て変更された部屋に入るようにしています。

クライアントサイドの記述

以下の記述になります。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>chat app node.js</title>
  <script src="/socket.io/socket.io.js"></script>
  <script src="//code.jquery.com/jquery-1.11.1.js"></script>
  <style>
  * {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
  }
  body {
    font-family: Verdana;
  }
  ul {
    list-style-type: none;
    padding: 20px;
    background: #000;
    color: white;
  }
  #controls {
    position: absolute;
    bottom: 0px;
    left: 0px;
    padding: 20px;
    display: block;
    width: 100%;
  }
  #controls #msj {
    float: left;
    width: 80%;
    display: block;
    padding: 20px;
  }
  #controls #btn {
    float: right;
    padding: 20px;
  }
  #controls #channel {
    display: block;
    width: 100%;
    font-size: 2em;
  }
  </style>
</head>
<body>
  <script>
    <!-- サーバー側とつなぐため -->
    var socket = io();

    $(function() {
      <!-- 送信されたときの処理  -->
      $('form').submit(function() {
        <!-- メッセージを取得 -->
        var mensaje = $('#msj').val();

        <!-- メッセージがなければ終了 -->
        if (mensaje === '') return false;

        <!-- メッセージを送信 -->
        socket.emit('message', mensaje);

        <!-- メッセージの中身を空にしえフォーカスする -->
        $('#msj').val('').focus();
        return false;
    });

     <!-- チャンネルを変えた時の処理 -->
     $('#channel').on('change', function() {
       <!-- チャンネル変更する -->
       socket.emit('change channel', $('#channel').val());
     });
   });

    <!-- メッセージが送信された時の処理 -->
    socket.on('message', function(msj, id) {
      <!-- 取得したメッセージをulに追加 -->
      $('#message').append($('<li>').text(id + " : " + msj));
    });

    <!-- チャンネルが変わった時の処理 -->
    socket.on('change channel', function(channel) {
      <!-- チャンネルが変わったことをメッセージで表示 -->
      $('#message').html('').append($('<li>').text('チャンネルが ' + channel + 'に変更されました!'));
    });
  </script>
  <ul id="message"></ul>
  <div id="controls">
    <form action="">
    <select name="channel" id="channel">
      <option value="channel-a">Channel-A</option>
      <option value="channel-b">Channel-B</option>
    </select>
    <input type="text" id="msj" placeholder="メッセージを入力してください...">
    <input type="submit" id="btn" value="Enviar">
    </form>
 </div>
</body>
</html>

チャンネルを切り替える用のプルダウンを追加して、それが変更された時のイベントを追加しています。

動かす

これを動かすと以下のようになります。

少し見づらいですが、同じチャンネルだけでメッセージがやりとりされています。

161013_1

デモが用意できず申し訳ないです。でもおそらくコピペでできはずなので、実際に試してみてください!

参考動画

今回は以下の動画を参考にしました!!

以上!!

次回はついに、HerokuというWEBサービスを使ってリアルタイムチャットをWEBに公開したいと思います。

それができれば今度こそnode.jsを使ったゲームを作りたいと思います!

Pocket

コメント

コメントを残す