ロゴテキスト ロゴ

    express + socket.ioを使ったsocketサーバをサクッと立ち上げる

    express + socket.ioを使ったsocketサーバをサクッと立ち上げる

    Web Socketを使うプロジェクトを始める上でまず技術調査を行いたく、

    express + socket.ioのサーバをローカルに作ってみました。


    備忘録も兼ねてやったことを記載します。

    検証した環境

    1 express 4.18.1
    2 socket.io 4.5.0

    事前準備

    package.jsonを作成

    package.jsonを作ります

    $ yarn init -y

    nodeのバージョンを固定(Optional)

    あまりにnodeのバージョンが低くなければ基本動くと思うので状況に応じて。


    nodeのバージョンを2022/05/17現在LTSの 16.15.0 にします。

    # インストールとこのプロジェクトのバージョンを16.15.0に設定
    $ nodenv install 16.15.0
    $ nodenv local 16.15.0
     
    # 16.15.0が設定されている事を確認
    $ node -v
    v16.15.0


    Prettier導入(Optional)

    必須ではないですが、

    コード整形は自動でしたいのでPrettierを導入します

    $ yarn add -D prettier

    設定は簡単に済ませるため package.json に追記

    package.json
    {
      ・・・
      "prettier": {
        "singleQuote": true,
        "semi": false,
        "printWidth": 100,
        "arrowParens": "avoid"
      }
    }


    expressでHello World!

    express を導入します

    $ yarn add express


    確認のため試しに Hello World! を表示してみます。


    app.jsをpackage.jsonと同じ階層に作成

    app.js
    const express = require('express')
    const app = express()
    const port = 3000
     
    app.get('/', (req, res) => {
      res.send('Hello World!')
    })
     
    app.listen(port, () => {
      console.log(`Example app listening on port ${port}`)
    })

    expressを立ち上げるコマンドをnpm-scriptsに追加

    package.json
    {
      "scripts": {
        "serve": "node app.js"
      },
    }


    これでyarn run serveでサーバが立ち上がるので、

    http://localhost:3000/ にアクセスしてみます。

    $ yarn run serve
    ・・・
    Example app listening on port 3000
    localhost:3000にアクセスするとHello World!が表示される

    ↑のように表示されます!


    socket.ioの導入

    1番重要なパッケージを導入します!

    $ yarn add socket.io


    socket.ioの公式ページに記載されているものにプラスで記載します

    Get started | Socket.IO


    app.js
    const express = require('express')
    const app = express()
    const http = require('http')
    const server = http.createServer(app)
    const { Server } = require('socket.io')
    const io = new Server(server)
     
    const port = 3000
     
    io.on('connection', socket => {
      console.log('a user connected')
     
      socket.on('my-event-a', message => {
        console.log(`from client. ${message}`)
        // 送信元も含めすべてのsocketに対してメッセージを送信する
        io.sockets.emit('my-event-b', `from server. ${message}`)
      })
    })
     
    server.listen(port, () => {
      console.log(`Example app listening on port ${port}`)
    })

    上記のsocketサーバがやっている事は my-envet-aというイベントを受け取ったら、my-envet-bというイベント名でサーバから送信します。


    公式で公開されている図と同じですね。


    The Socket instance (server-side) | Socket.IO より引用


    socket.ioと疎通確認

    socket.ioが動いているか簡単に確認します。



    yarn run serveでサーバを起動し、公式に書かれているcurlコマンドで確認します

    接続の問題のトラブルシューティング| Socket.IO

    $ curl "http:localhost:3000/socket.io/?EIO=4&transport=polling"
    0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}

    curlコマンドでsid: xxxxのように返ってきます。


    これでsocket.ioが生きている事が確認出来ます!



    とはいえこれだとsocket通信らしい双方向通信が出来ているのか分からない 😅




    htmlで確認する

    というわけで、

    ブラウザ上で クライアント ⇔ サーバ でソケット通信出来ることを確認出来るようにしていきます。



    index.html をapp.jsと同じ階層に作成します

    index.html
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <title>socket.io sample</title>
      <script src="/socket.io/socket.io.js" ></script>
      <script src="https://code.jquery.com/jquery-1.11.1.js" ></script>
      <script>
        var socket = io();
     
        $(function(){
          $('#form').submit(function(){
            // inputに入力した内容を my-event-a という名前のイベントを送る
            socket.emit('my-event-a', $('#input').val());
            $('#input').val('');
            return false;
          });
     
          // my-event-b という名前のイベントを受け取ったら li を作る
          socket.on('my-event-b',function(msg){
            $('#messages').append($('<li>').text(msg));
          });
        });
      </script>
    </head>
    <body>
    <ul id="messages"></ul>
    <form id="form">
      <input id="input" autocomplete="off" /><button>Send</button>
    </form>
    </body>
    </html>

    懐かしのjQuery 😎


    そしてapp.jsでexpressを使ってindex.htmlを返すようにします

    app.js
    app.get('/', (req, res) => {
      res.sendFile(__dirname + '/index.html')
    })



    これで実際にブラウザで確認します

    • 右側でサーバを起動
    • 左側で2つのブラウザでソケット通信が出来ている事を確認

    上のブラウザで更新すれば、下のブラウザも更新されるようになりました!



    Postmanで確認(2022/05/18 追記)

    html以上に手軽に確認する方法としてPostmanを使う方法がありました!




    以下の動画のように簡単にsocket.ioを用いた双方向通信が確認出来ます

    (詳細は上記記事参考にして下さい)

    プロフィールの背景画像 プロフィール画像
    Yuki Takara
    都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。