0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

いまさらWebSocketに触ってみる

Posted at

Websocketとは

クライアントとサーバー間の間で双方向通信を可能にするプロトコルです。

  • 一度接続が確立されると、新しいリクエストを送る必要なく通信できます
  • ws://(暗号化なし)またはwss://(暗号化あり)から始まります

活用シーンは、チャットアプリやリアルタイムのゲームなど即時性が求められる場面で活用されます。

WebsocketとHTTPとの違い

  • HTTP:クライアントからのリクエストに対してサーバーが応答する一方向の通信
  • WebSocket:クライアントとサーバーが双方からデータを送信可能

触ってみた結果

2つのブラウザを立ち上げて、リアルタイムで別ブラウザにデータが送信されるかを検証しました。

  1. 2つのブラウザを開く
  2. 片方のブラウザのinputボックスにデータを入力する
  3. 「送信」ボタンを押す

結果、送信ボタンを押した後、もう片方のinputボックスのデータが即座に更新されました!

websocket.gif

前提

下記の技術で構成しています。

  • フロント

    • Typescript
    • React
  • バックエンド

    • Express

ソースコード

パッケージのインストール

Socket.ioライブラリを使用して検証しました。

バックエンド

npm i socket.io

フロントエンド

npm i socket.io-client

バックエンド

import express from 'express';
import 'dotenv/config'
import { Server } from 'socket.io';
import { createServer } from 'node:http';

const PORT = process.env.PORT;

const app = express();
const server = createServer(app);
const io = new Server(server, {
  cors: {
    origin: '*',
    methods: ['GET', 'POST']
  }
});

app.use(express.json());
app.use(express.urlencoded({ extended: true}));

io.on('connection', (socket) => {
  socket.on('chat message', (msg) => {
    io.emit('chat message', msg);
  });
})

server.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

フロントエンド

import React, { useEffect, useState } from 'react';
import io from 'socket.io-client';

export const Websocket = () => {
  const [message, setMessage] = useState('');

  const socket = io('ws://localhost:3000');
  useEffect(() => {
    // WebSocket接続を確立
    socket.on('connect', () => {
      console.log('WebSocket connected');
  });
    // コンポーネントがアンマウントされたときにクリーンアップ
    return () => {
      socket.disconnect();
    };
  }, [socket]);

  const handleInputChange = (event: { target: { value: React.SetStateAction<string>; }; }) => {
    setMessage(event.target.value);
  };

  const submitMessage = () => {
    socket.emit('chat message', message);
  }

  socket.on('chat message', (msg) => {
    setMessage(msg)
  })

  return (
    <div>
      <div>下記に入力</div>
      <input type="text" style={{border: '1px solid black'}} value={message} onChange={handleInputChange}/>
      <button onClick={submitMessage}>送信</button>
      <div>下記に出力</div>
      <div>{message}</div>
    </div>
  );
}

説明

const socket = io('ws://localhost:3000');

サーバーへの接続を作成し、インスタンスを返却しています。

socket.emit('chat message', message);

データをサーバーに送信しています。
上記のコードは第一引数で イベントの名前を指定し、第二引数でデータをサーバーに送信しています。

socket.on('chat message', (msg) => {

第一引数に指定したイベントをリッスン(特定のイベントや状態変化が起きるのを待ち受けている状態)します。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?