2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js+Express+Socket.ioを使ってソケット通信を行う

Last updated at Posted at 2023-01-18

初めに

研究でソケット通信を行う必要があったので、Socket.ioを使って実装しました。
クライアントはNext.js、サーバーはExpressを用いています。

この記事は、Next,jsとExpressを使ったことがある人を対象としています。

今回の記事は以下のサイトを参考にしています。
Socket.IO + Express + TypeScriptでリアルタイム通信を始めよう

Socket.ioとは?

WebSocket技術によるリアルタイム双方向通信処理を簡単に実装するためのnode.js用サーバー側ライブラリとブラウザ用JavaScriptライブラリ。

モデルの実装

今回はTypeScriptを使っているので、事前に型定義が必要となります。
そのため、サーバー、クライアント共に使えるモデルを作成しておきます。

model.ts
//イベントの送信およびブロードキャスト時に使用される型定義
export type ServerToClientEvents = {
  hello: (message: string) => void;
};

//イベント受信時に使用する型定義
export type ClientToServerEvents = {
  message: (message: string) => void;
  player:(name:string) => void;
};

サーバーサイドの実装

まず初めに以下のパッケージをインストールします

npm install typescript express socket.io ts-node
npm install -D @types/express @types/node

次にコードを記述します。

server.ts
import express from "express";
import { createServer } from "http";
import { Server } from "socket.io";
//モデル読み込み
import { ClientToServerEvents, ServerToClientEvents } from "./models";

const app = express();
const httpServer = createServer(app);
const io = new Server<ClientToServerEvents, ServerToClientEvents>(httpServer,
//CORS対策
{
  cors: {
    origin: ["http://localhost:3000"],
  },
});
// コネクション確立
io.on("connection", (socket) => {
  console.log(socket.id);

  // イベント発行
  socket.emit("hello", "from server");

  // イベント受信
  socket.on("message", (message) => {
    console.log(`from client: ${message}`);
  });

  // 切断イベント受信
  socket.on("disconnect", (reason) => {
    console.log(`user disconnected. reason is ${reason}.`);
  });
});

// サーバーを5000番ポートで起動
httpServer.listen(5000, () => {
  console.log("Server start on port 5000.");
});

参考記事にはCORS対策が記載されていなかったので、追加してあります。
CORSについて知りたい方は以下のサイトをご覧ください。
オリジン間リソース共有 (CORS)

次に起動用コマンドをpackage.jsonに記述します

package.json
"scripts": {
  "server": "ts-node server.ts"
}

npm run serverで実行できます。

警告
MacOS Monterey 12以降 、ポート5000を利用しようとするとAddress already in userが発生することがあります。これは、「AirPlayサーバー」がポート5000を利用していることにより発生する問題です。設定 > Airplayから「AirPlayレシーバー」のチェックを外してください。その後、ターミナルでlsof -i:5000を実行後、kill -9 表示されたPIDを実行してください。

クライアントサイドの実装

Next.jsのプロジェクトは既に作成してあるものとして進めます。
パッケージをインストール

npm install socket.io-client

pages/index.tsx にコードを追加します。(追加したコードのみ記載)

index.tsx
//パスは変更してください
import { ClientToServerEvents, ServerToClientEvents } from "../src/models";
import { io, Socket } from "socket.io-client";

export default function Home(){
  useEffect(()=>{

    const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io(
      // サーバーのURLを指定
      "http://localhost:5000"
    );

    socket.on("connect", () => {
      console.log(socket.connected);
    });
    
    socket.on("hello", (message) => {
      console.log(message);
    });
    
    socket.emit("message", "hello world");

  },[])
}

npm run devで実行できます。

終わりに

Socket.ioを使えば非常に簡単にソケット通信ができるので、ぜひ使ってみてください。
CORS対策はお忘れないように!

2
4
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
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?