0
0

やさしいsocket.io

Last updated at Posted at 2024-05-27

はじめに

非同期通信はハードル高いって思ってる方(昔の自分)へ
ゆっくりしっかり理解していったら、簡単じゃん
ってなるので、チャットルームを作成して楽しんでね

javascriptnode.jsの知識を前提としております

node.jsのモジュールであるsocket.ioの使い方

1. 概要

webSocket
サーバーからプッシュする(双方向)
たまに対応していないブラウザやバージョンがある

2. 導入

npm install socket.io

3. 基本的な記述方法

Socket通信
emit データの送信
on 接続の待ち受け

クライアント側

client.html
<!-- ライブラリの取得(CDN) -->
<script src="/socket.io/socket.io.js"></script>
<script>
// Socket接続(コネクション)
const socketio = io();
// サーバーに送信
socketio.emit('c2s', input_msg);
// 待ち受け
socketio.on('s2c', function(msg){
   console.log('ソケットs2c: '+msg);
});
</script>

サーバー側

server setup

ExpressとSocket.IOを統合してWebSocketサーバーを作成

server.js
// official
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const socketio = new Server(server);

上記をいろいろ省略して記述したものが下記

server.js
// simplex
const express = require('express');
const app = express();
const Server = require('http').Server(app);

サーバーの起動

server.js
const socketio = require('socket.io')(Server);
Server.listen(config.port);
// Socket接続(コネクション)
socketio('connection',(socket)=>{
   // クライアントに送信
   socket.emit('s2c', server_msg); // only the client
   socketio.emit('s2c', server_msg); // all client
   // 待ち受け
   socket.on('c2s', function(msg){
      console.log('ソケットc2s: '+msg);
   });
})
ソケット通信で変数を使いたい場合
server.js
// ここ宣言した変数は全クライアントで共通利用
socketio('connection',(socket)=>{
   // ここで宣言した変数は各クライアントで利用
})

4. 応用的な記述方法

送信タイミングの指定

client.html
const socketio = io(); // サーバーへ接続
// ソケット接続確立直後に送信
socketio.on('connect', () => {
  // socketID : 001
  socketio.emit('login', my_user_name);
});

connect イベントはクライアントがサーバーに接続したことを通知するための特別なイベントです。クライアントがサーバーに接続すると、Socket.io は自動的に connect イベントを発生させます。

client.html
// ボタン押下時
const form = document.getElementById("chat-form");
form.addEventListener("submit", function(event){
    event.preventDefault(); // イベントに関連するデフォルトの動作を防ぐ
    const input_message = document.getElementById("get-text").value;
    socketio.emit('c2s', input_message); // サーバーに送信
});
// ボタン押下時2
const submitBtn = document.getElementById("submit-btn");
submitBtn.addEventListener("click", ()=>{
    const input_message = document.getElementById("get-text").value;
    socketio.emit('c2s', input_message); // サーバーに送信
});

複数のデータ(オブジェクト)の送受信

client.html
const sendData = {
   input1 : document.getElementById("chat-input1").value,
   input2 : document.getElementById("chat-input2").value
};
socketio.emit('c2s', sendData); // サーバーに送信
server.js
socket.on('c2s',function(msg){ // データ「c2s:msg」を受信したら
   console.log('c2s[input1]: ' + msg.input1);
   console.log('c2s[input2]: ' + msg.input2);
});

5. room

roomは双方向・リアルタイムデータ送受信を任意の範囲で行うための仕組み。
roomを使用すると、その部屋に所属するクライアント間のみでデータをやり取りすることが可能。

(ネットワークのマルチキャスト通信みたいなイメージ)
(socketio.emit('s2c', server_msg); // only the clientがブロードキャスト)
(socket.emit('s2c', server_msg); // all clientがユニキャスト)

動きの流れ

  1. クライアントがルーム名(namespace)を送信

    client.html
    socket.emit('joinRoom', 'room1');
    
  2. サーバーがルーム名を受け取り、参加

    server.js
    socket.on('joinRoom', (room) => {
       socket.join(room);
    });
    
  3. クライアントからの送信はネームスペースを付ける

    client.html
    const sendData = {
       room: "1",
       message: document.getElementById("message-input").value,
    }
    socket.emit('roomMessage', sendData);
    
  4. サーバーからの送信はルーム名を付ける

    server.js
    socket.on('roomMessage', (data)=>{
       socketio.to(data.room).emit('message', data,message);
    });
    
  5. クライアントが待ち受ける

    client.js
    socketio.on('message', (msg) => {
       console.log('s2c_msg:', msg);
    });
    

6. まとめ

client.html
<div class="contents">
   <h2>chat space</h2>
   <ul id="chat_output"></ul>
   <form id="chat-form">
      <input type="text" name="get_text" id="get-text">
      <input type="submit" value="GET送信">
   </form>
</div>
<!-- ライブラリの取得(CDN) -->
<script src="/socket.io/socket.io.js"></script>
client.js
// Socket接続(コネクション)
const socketio = io();
// ルームに参加する
socketio.on('connect', () => {
   const sendData = {
      chatid: "1"
   }
   socketio.emit ('c2s-join', sendData);
});
// ボタン押下時
const form = document.getElementById("chat-form");
form.addEventListener("submit", function(event){
   event.preventDefault(); // イベントに関連するデフォルトの動作を防ぐ
   const sendData = {
      chatid: "1",
      input: document.getElementById("get-text").value,
   }
   socketio.emit('c2s', sendData);
});
// サーバーからメッセージを受信したときの処理
socketio.on('s2c', (msg) => {
   // htmlに表示
   let ul = document.getElementById("chat_output");
   let li = document.createElement('li');
   li.innerHTML = msg;
   ul.appendChild(li);
});
server.js
const express = require('express');
const app = express();
const Server = require('http').Server(app);
const socketio = require('socket.io')(Server);
// サーバー起動
Server.listen(config.port);

// Socket接続(コネクション)
socketio('connection',(socket)=>{
   // ルームに参加する
   socket.on('c2s-join', (data)=>{
      socket.join(data.chatid);
      console.log(`${socket.id} joined room ${data.chatid}`);
   });
   // 待ち受け
   socket.on('c2s', (msg)=>{
      // クライアントに送信
      socket.emit('s2c', server_msg); // only the client
      socketio.emit('s2c', server_msg); // all client
      socketio.to(data.chatid).emit('s2c', data,input);
   });
   // クライアントが切断したときの処理
   socket.on('disconnect', () => {
      console.log('Disconnected:', socket.id);
   });
})
0
0
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
0
0