プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Webサービス開発
  • 【Web開発】「Socket.IO」の基本、実装方法、sticky-session
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Web開発】「Socket.IO」の基本、実装方法、sticky-session

12.20

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

WebSocketを扱うことができるNode.jsのライブラリです。

WebSocketを直接扱うのとの違い

WebSocketを単体で扱っても実装は可能です。Socket.IOを使うメリットは以下です。

他の通信をサポートしている。

WebSocketがサポートされていない環境でもポーリングや、JSONPなどの他の通信機能を用いて通信ができるので幅広い環境で活用できます。

接続されている全てのクライアントにブロードキャストできる

プレーンなWebSocketの場合は、接続されているクライアントのリストを見て一回一回送信する必要があります。

自動的に再接続してくれる

プレーンなWebSocketの場合は、自動的に再接続はしてくれません。再接続の処理を記述する必要があります。

リリースノート

1.0.0

2014年5月にリリースされた。旧バージョン(1.0.0以前)のAPIが廃止されたので互換性がない。

できること

チャットなどの送受信されるメッセージ内容が即時反映されるリアルタイムWebアプリケーションを実装することが可能です。

制約

誰かが書き込んだら、リアルタイムで他のユーザーにも反映されます。Socket.IOサーバーが全てのクライアントに通知してくれる仕組みです。ただし、全ての利用ユーザーがオンラインである必要があります。

P2Pではダメなのか?

いちいち、Socket.IOサーバーが必要になるので、サーバーのいらないP2P接続じゃダメなの?と思われるかもしれませんが、それだとNATやFirewallを超えるSTUNサーバーなどを用意する必要があり結局サーバーが必要になってしまうのでどっちもどっちになるためです。

大まかな仕組み

何か、イベントが発生した時に動く「イベント駆動」になっています。

チャットで呟いた人が、postイベントを送信すると、他の全クライアントに対して「member-post」というイベントを別途発行します。

room、namespace

Socket.ioはデータ送受信だけでなく、roomやnamespaceなどのライブラリも提供しています。

room

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

namespace

Socket.IOの実装を機能単位で分割するための仕組み。チャットアプリに外部API連携機能や、お知らせ機能などを実装したい場合はこれを使って実装するとよい。

実装

socket.ioを使う場合は、フロントエンドとバックエンドでそれぞれやりとりを行うのでそれぞれの書き方を把握する必要があります。

初期化

フロントエンド

以下の例で言えば、ルートパスとコネクトします。socket.ioではioオブジェクトを使用して通信経路を開きます。

1
const socket = io("http://サーバーのIP:ポート番号");

通常のwebsocket APIと異なりsocket.ioはWebSocket以外のプロトコルにも対応しているのでwsではなく、httpになっています。

バックエンド

Node.js環境でフレームワークにExpressを使う場合は下記のように記述します。どのサーバーでソケット通信をするかsocket.ioに伝えます。

1
2
3
4
const express = require("express");
const app = express();
const server = require("http").Server(app);
const io = require("socket.io")(server);

イベント送信

フロントエンド

1
socket.emit("イベント名", 送信パラメータ1,送信パラメータ2);

バックエンド

同じルーム内の全てのユーザーに送信できます。(ブロードキャスト)

1
socket.broadcast.emit("イベント名", 送信パラメータ);

イベント受信

これも基本バックエンドも、フロントエンドも同じ書き方です。

第二引数でコールバック関数を指定します。

1
2
3
socket.on("イベント名", (受信パラメータ) => {
  やりたいこと。
});

バックエンドの場合

一旦、サーバーでつかまえてからsocketのイベントハンドラの登録をします。

1
2
3
io.on("connection", (socket) => {
  socket.on("xxx",()=>{})
}

バックエンドのみ:ルームに新規ユーザーを追加

ルームに新規ユーザーを追加します。

1
socket.join(roomId);

フロントエンドのみ:ソケット通信を切断する。

1
socket.disconnect();

sticky-sessionとは?

socket.ioのサーバーをclusterモジュールを使ってスケールアウトしようとした際に、コネクション確立時に別のプロセス(サーバー)が割り振られてしまうのでエラーになる。これを解決する仕組みです。

仕組み

内部でclusterが使われていてsticky.listenというAPIを呼べば複数のプロセスを自動でforkしてくれます。デフォルトで使っているサーバーのCPUの数だけforkします。

実装例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const cluster = require("cluster");
const io = require("socket.io")();
const sticky = require("sticky-session");
const http = require("http");
 
const server = http.createServer((req, res) => {
  res.end("worker: " + cluster.worker.id);
});
 
io.attach(server);
isWorker = sticky.listen(server, 3000);
 
console.log(isWorker);
 
if (isWorker) {
  io.on("connection", (socket) => {
    console.log(`worker: ${cluster.worker.id}, connected, id: ${socket.id}`);
    // socket.ioの処理
  });
}

スポンサーリンク
  • 2021 12.20
  • miyabisan2
  • コメントを書く
  • Webサービス開発
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2019 12.08

    【Web開発】「戻る」操作について

  2. 2019 12.09

    【Web開発】「無限スクロール」、「確認画面」、「登録画面」、「CSVインポート機能」、「メール送信機能」、「ランキング機能」、「メンテナンスページ」の設計

  3. 2018 04.29

    【システム開発】開発モデル、開発手法の種類

  4. 2021 09.12

    【Web開発】「push通知」の基本、設計のポイント

  5. 2019 11.30

    【Web開発】ユーザー管理機能の設計や実装、認証設計の種類

  6. 2019 12.09

    【Web開発】「子画面」について

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【マルチメディア】「コーデック」と「動画形式」について

【TypeScript】「ESlint」の初期設定コマ…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー