Socket.IOの使い方

本記事では、WebRTCの開発にも使用されるNode.jsライブラリ「Socket.IO」の使い方をまとめて紹介します。Socket.IOは、リアルタイムな双方向通信を簡単に実現できる強力なライブラリで、WebRTCと組み合わせることで、音声やビデオチャットなどのリアルタイムアプリケーションの開発が容易になります。

インストール

WebサーバーにはExpressを使用するため、Expressもインストールします。

npm install socket.io
npm install express

サーバー <-> クライアント間の通信

サーバー側のサンプルソースコード

const path = require('path');
const http = require('http');
const express = require('express');
const app = express();

const port = 80;
const server = http.createServer(app).listen(port, () => {
  console.log(`server start. port=${port}`);
});
const io = require('socket.io')(server);

io.on('connection', (socket) => {
  console.log(`socket.id:${socket.id}`);

  // 切断時に発生します.
  socket.on('disconnect', (reason) => {
    console.log(`disconnect: %s, %s`, reason, socket.id);
  });

  socket.on('client-send', (data) => {
    socket.broadcast.emit('server-send', { message: data.message }); // 送信者以外
  });
});

// expressで静的ページにアクセスする.
app.use(express.static(path.join(__dirname, 'static')));
変数ioの定義(代入)方法は一例で、他の指定もあります。

クライアントとの通信は、上記のコールバック関数内で記述します。socketは接続された各クライアントを指します。通信は、双方向に行うことが可能です。

イベントを送信する場合は、socket.emit(eventname, data)を使用します。一方、イベントを受信する際は、socket.on(eventname, callback)や、socket.on(eventname, callback(data))を使って、特定のイベントがトリガーされたときに適切な処理を実行します。これにより、リアルタイムなデータの送受信が容易に行えます。

サーバーからクライアント、またはクライアントからサーバーへイベントを送受信する際に使用するメソッド名は、どちらの方向でも同じです。
双方向の通信に同じ構文で使用できるため、実装がシンプルになります。

サーバーがクライアントからのイベントを受信する

クライアントからのイベントをsocket.on(eventName, callback)で受信します。

socket.on(eventname, data => {
  //
});

部屋に入室する

socket.join('部屋名');

部屋から退室する

socket.leave('部屋名');

サーバーからクライアントへイベントを送信する

サーバーからクライアントにイベントを送信する際は、以下のような方法を使用します。

特定のクライアントにイベントを送信する

socket.emit('イベント', 'データ');

このコードでは、サーバーから特定のクライアントに対して、イベント名と、送信するデータを送信します。socket.emitを使うことで、サーバーとクライアント間でリアルタイムな通信を簡単に実現できます。

ここで、特定のクライアントを表す変数socketconnectionイベントで通知されたオブジェクトです。

特定のクライアントだけでなく、すべての接続されたクライアントにイベントを送信する

io.emit('イベント', 'データ');

特定のクライアントを除く、すべての接続されたクライアントにイベントを送信する

socket.broadcast.emit('イベント', 'データ');

特定のクライアントにイベントを送信する

送信先のソケットIDは相手側のsocket.idで取得できます。

io.to(送信先のソケットID).emit('イベント', 'データ');

特定の部屋のクライアントにイベントを送信する

部屋に所属するすべてのクライアントにイベント送信します。

io.to('部屋名').emit('イベント', 'データ');

クライアント側のサンプルソースコード

static/client.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Socket.io Client</title>
  <script src="/socket.io/socket.io.js"></script>
</head>
<body>
  <div id="socketStatus" style="line-height: 1em; height: 1em;"></div>
  <div>
    <p>
      送信メッセージ:<input type="text" name="sendmessage" value="" id="sendMessage" style="width: 200px;">
    </p>
    <p>
      <button type="submit" onclick="sendMessage();">送信</button>
    </p>
    <p>
      受信メッセージ:<input type="text" name="receivemessage" value="" id="receiveMessage" style="width: 200px;" readonly>
    </p>
  </div>
<script>
  let socket = io('http://localhost');

  socket.on('connect', () => {
    // サーバーに接続できた
    console.log('connect success');
  });

  socket.on('disconnect', (event) => {
    // サーバーから切断された
    console.log('disconnect', event);
  });

  socket.on('server-send', (data) => {
    // サーバーから'server-send'イベントを受信
    let message = data.message;
    document.getElementById('receive-message').value = message;
  });

  function sendMessage() {
    let message = document.getElementById('send-message').value;
    socket.emit('client-send', { message: message });
  }
</script>
</body>
</html>

サーバーに接続する

// サーバーに接続
let socket = io('http://localhost');

socket.on('connect', () => {
  // サーバーに接続できた
  document.getElementById('socketStatus').innerHTML = 'connect success';
});

以下の接続は、どれも同じ接続となる。

let socket = io('/');
let socket = io.connect();
let socket = io.connect('/');

サーバーからの切断イベント受信

socket.on('disconnect', (event) => {
  document.getElementById('socketStatus').innerHTML = 'disconnect';
});

クライアントがサーバーからのイベントを受信する

サーバーからのイベントはsocket.on(eventName, callback)で受信します。

socket.on('イベント', (data) => {
  //
});

クライアントからサーバーへイベントを送信する

クライアントからサーバーへのイベント送信はsocket.emit(eventName, data)を使用します。

socket.emit('イベント', 'データ');
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です