Help us understand the problem. What is going on with this article?

node.jsでsoket.ioを使用して簡単なチャットを作成してみた

まずはsocket.ioモジュールを追加しましょう。

https://www.npmjs.com/package/socket.io

npm i socket.io

で追加します。

1.まずはサーバーサイドのコードを書いてみます
説明はコード内のコメントを読んでいただけるとありがたいです。

SoketIoServerTest.js
//httpモジュール読み込み
var http = require( 'http' );

// Socket.IOモジュール読み込み
var socketio = require( 'socket.io' );

 // ファイル入出力モジュール読み込み
var fs = require( 'fs' );

//パスのモジュール読み込み
const path = require('path');

//8080番ポートでHTTPサーバーを立てる
var server = http.createServer( function( req, res ) {
  //リクエストされたファイルパスを取り出す
  var filePath = "." + req.url;
  console.log(filePath);

  //ファイルパスのファイル名がなければindex.html
  if (filePath == './') {
      filePath = './index.html'
  }

  //拡張子名を取り出す
  var extname = String(path.extname(filePath)).toLowerCase();
  console.log('extenname:' + extname);

 //拡張子に対応するコンテンツ表
  var mimeTypes = {
    '.html': 'text/html',
    '.js': 'text/javascript',
    '.css': 'text/css',
    '.json': 'application/json',
    '.png': 'image/png',
    '.jpg': 'image/jpg',
    '.gif': 'image/gif',
    '.wav': 'audio/wav',
    '.mp4': 'video/mp4',
    '.woff': 'application/font-woff',
    '.ttf': 'application/font-ttf',
    '.eot': 'application/vnd.ms-fontobject',
    '.otf': 'application/font-otf',
    '.svg': 'application/image/svg+xml',
    '.ico': 'image/x-icon'
};

 //MIMEがない場合はデフォルトを使用
 var contentType = mimeTypes[extname] || 'application/octet-stream';
 

  //リクエストされたファイルパスを読み込み
  fs.readFile(filePath, function(error, content) {

    //エラー処理
    if (error) {
      console.log('ERROR!!' + error.code);
        //リクエストしたファイルが存在しない場合
        if (error.code === 'ENOENT') {
          //ファイルパスの先にファイルがないエラー
          res.writeHead(404);
          res.write('Sorry, check with the site admin for error: '+error.code+' ..\n404');
          res.end();

      } else {
        //CGIエラー
        res.writeHead(500);
        res.write('Sorry, check with the site admin for error: '+error.code+' ..\n500');
        res.end();
      }
    } else {
      //エラーがない場合、正常処理
      res.writeHead(200, { 'Content-Type': contentType });
      res.end(content, 'utf-8');


    }
  });



}).listen(8080);

//サーバーをソケットに紐づける
var io = socketio.listen( server );

//接続確立後の通信処理部分を定義
io.sockets.on( 'connection', function( socket ){
  var name;
  console.log('コネクション:' + socket);

  //クライアントからサーバーへメッセーゾ送信ハンドラ(自分を含む全員に送る)
   socket.on( 'c2s_message', function( data ) {

//サーバーからクライアントへメッセージ送り返し
  io.sockets.emit( 's2c_message', { value : data.value } );
  console.log('通常メッセージ:' + data.value);

});

  //サーバーからクライアントへメッセージ送信ハンドラ(自分以外の全員に送る)
  socket.on( 'c2s_broadcast', function( data )  {

    //サーバーからクライアントへメッセージ送り返し
    socket.broadcast.emit( 's2c_message', { value : data.value } );
    console.log('ブロードキャストメッセージ:' + data.value);

  });

  socket.on('c2s_personal', function( data ){

    var id = socket.id;
    name = data.value;
    var personalMessage = 'あなたは、' + name + 'さんとして入室しました。';
    console.log('ゆーざーID:' + id);

    io.to(id).emit('s2c_message',{ value: personalMessage });

  });
});

2.次はクライアント側のjavascriptを書いてみます
こちらも説明はコード内のコメントを読んでいただけると幸いです。
ちなみにjQueryを使用しています。index.htmlの方で読み込んでおいてくださいね。

js/clienttest.js
//空のioSocket用意
var ioSocket = { on: function(){}};

function connect() {
  if(!ioSocket.connected){
//サーバーへ接続
ioSocket = io.connect('http://' + window.location.host);
console.log('URL:' + window.location.host);
console.log('サーバー接続!!');
} else {
  //サーバーへ再接続
  ioSocket.connect();
  console.log('サーバー再接続!!')
}
}

connect();

//サーバーからの受け取り処理
ioSocket.on('connect',function(){});
ioSocket.on('disconnect',function(){});

var isEnter = false;
var userName;

//サーバーからの送り返し
ioSocket.on('s2c_message',function( data ){ appendMessage( data.value ) });

//画面にメッセージを描画
function appendMessage( text ) {
  $('#messageView').append('<div>' + text + '</div><br/>');
    console.log("メッセージ:" + text);
}


//自分を含む全員宛てにメッセージを送信
$('#sendMessageBtn').on('click',function(){
  //メッセージの内容を取得し、フォームをレフレッシュ
  var message = $('#messageForm').val();
  $('#messageForm').val('');

  //入室処理
  if (isEnter) {
    message = '[' + userName + '] ' + message;
  //クライアントからサーバーへ送信
  ioSocket.emit('c2s_message',{ value: message });
} else {
  userName = message;
  var entryMessage = userName + 'さんが入室しました。';
  ioSocket.emit('c2s_broadcast',{ value: entryMessage });


  ioSocket.emit('c2s_personal' ,{ value: userName });
  changeLabel();
}
});

function changeLabel() {
  $('input').attr('placeholder','message In');
  $('button').text('送信');
  isEnter = true;
}

$(window).on("beforeunload",function() {
        var getoutMessage = userName + 'さんが退室しました。';
        ioSocket.emit('c2s_broadcast',{ value: getoutMessage});
        ioSocket.disconnect();
    });

3.簡単なhtmlを作成します。

index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
    <script type="text/javascript" src="./lib/jquery-3.4.1.min.js"></script>
    <script type="text/javascript" src="node_modules/socket.io-client/dist/socket.io.js"></script>
</head>
<body>
    <style>
    #messageForm {
        margin-top: 15px;
    }
    </style>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="form-group">
<input type="text" class="form-control" id="messageForm" placeholder="name In" />
<button class="btn btn-primary" id="sendMessageBtn">入室</button>

</div>
<div id="messageView"></div>
</div>
</div>
</div>

<script type="text/javascript" src="js/clienttest.js"></script>

</body>
</html>

では、ターミナルを開いて
node サーバーファイル名

で起動してからブラウザで
http://localhost:8080/
にアクセスしてみましょう。

このような動作になるかと思います。

スクリーンショット 2020-04-19 16.00.01.png

ブラウザの別タグでログインしてメッセージを送信してみます。

スクリーンショット 2020-04-19 16.05.57.png

メッセージが来ました!!さらに同一Lan内であればスマートフォンでチャットも出来ます。送信してみます。

Screenshot_20200419-160842.png

届きました!!

スクリーンショット 2020-04-19 16.13.27.png

以上で終わりですが動きがあるのは楽しいですね。

余談ですが
JavaとjavascriptでWebSocketを試してみよう!
https://qiita.com/keisuke1112/items/5c989eb8f0e868a25435

私の別記事でjavaとjavascriptでwebsocketを使用してみたのですが、node.jsの方が手軽に書けるような気がします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした