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

2022.05.18
2022.05.18
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

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


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を用いた双方向通信が確認出来ます

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

おすすめ