回答編集履歴

1

サンプルアプリのコードを追記しました。

2022/01/31 14:44

投稿

退会済みユーザー
test CHANGED
@@ -90,3 +90,167 @@
90
90
  混乱してしまっているように見えましたので、
91
91
  それらを整理した上で少しずつ記述すると良いと思いました。
92
92
 
93
+ ## 追記
94
+
95
+ 追記です。
96
+ 最小限のサンプルアプリを書いてみました。
97
+ 読んだだけでは理解できないところもあると思いますので、面倒でもご自身で一度動かしてみることが大切かな?と思います。
98
+ ショートカットしようとすると後でそのツケを払うことになり、結果的に遠回りになってしまう、というのが個人的な経験則です・・
99
+
100
+ ```js
101
+ // app.js
102
+ const express = require("express")
103
+ const { createServer } = require("http")
104
+ const { Server } = require("socket.io")
105
+
106
+ const app = express()
107
+ const httpServer = createServer(app)
108
+ const io = new Server(httpServer, { /* options */ })
109
+ const port = 3000
110
+
111
+ app.set("view engine", "pug")
112
+
113
+ app.get("/", (req, res) => {
114
+ res.render("index", { title: "Hey", message: "Hello there!" })
115
+ })
116
+
117
+ app.get("/window1", (req, res) => {
118
+ res.render("window1")
119
+ })
120
+
121
+ const socketPerRoom = 2
122
+ let socketCount = 0
123
+
124
+ io.on("connection", (socket) => {
125
+ console.log(`connection socket.id: ${socket.id}`)
126
+ socket.on("join", () => {
127
+ socketCount++
128
+ const room = `room${Math.ceil(socketCount / socketPerRoom)}`
129
+ // ソケットをルームに追加する
130
+ socket.join(room)
131
+ console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`)
132
+ // ルーム全体に送信する(最大2つのソケット)
133
+ io.to(room).emit("joined", socket.id, room)
134
+ })
135
+ })
136
+
137
+ httpServer.listen(port, () => {
138
+ console.log(`Example app listening on port ${port}`)
139
+ })
140
+ ```
141
+
142
+ .
143
+
144
+ ```pug
145
+ //- views/index.pug
146
+ html
147
+ head
148
+ title= title
149
+ body
150
+ h1= message
151
+ input(type="button", value="join", id="button1")
152
+ script.
153
+ window.addEventListener("DOMContentLoaded", () => {
154
+ const button1 = document.querySelector("#button1")
155
+ button1.addEventListener("click", () => {
156
+ //- 別ウィンドウで開く(Socket.IOの接続は別ウィンドウで)
157
+ window.open("/window1", "_blank")
158
+ })
159
+ })
160
+ ```
161
+
162
+ .
163
+
164
+ ```pug
165
+ //- views/window1.pug
166
+ html
167
+ head
168
+ title= "Window1"
169
+ script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous")
170
+ body
171
+ h1= "Window1"
172
+ ul(id="ul1")
173
+ script.
174
+ window.addEventListener("DOMContentLoaded", () => {
175
+ //- Socket.IO接続
176
+ const socket = io()
177
+ socket.on("connect", () => {
178
+ //- 接続した時のイベント
179
+ //- ソケットのIDをコンソールと画面のリストに出力する
180
+ console.log(`connect: ${socket.id}`)
181
+ const li1 = document.createElement('li')
182
+ li1.textContent = `connect socket.id: ${socket.id}`
183
+ const ul1 = document.querySelector("#ul1")
184
+ ul1.append(li1)
185
+ })
186
+ socket.on("disconnect", () => {
187
+ console.log(`disconnect: ${socket.id}`)
188
+ })
189
+ socket.on("joined", (socketId, room) => {
190
+ //- ルームに追加した時のイベント
191
+ //- ルームに追加されたソケットのIDとルームの名前をコンソールと画面のリストに出力する
192
+ console.log(`joined socketId: ${socketId}, room: ${room}`)
193
+ const li1 = document.createElement('li')
194
+ li1.textContent = `joined socketId: ${socketId}, room: ${room}`
195
+ const ul1 = document.querySelector("#ul1")
196
+ ul1.append(li1)
197
+ })
198
+ //- サーバーに送信する(ルームに追加するためのイベント)
199
+ socket.emit("join")
200
+ })
201
+ ```
202
+
203
+ .
204
+
205
+ ```json
206
+ // package.json
207
+ {
208
+ "name": "sample",
209
+ "version": "1.0.0",
210
+ "description": "",
211
+ "main": "app.js",
212
+ "scripts": {
213
+ "test": "echo \"Error: no test specified\" && exit 1"
214
+ },
215
+ "author": "",
216
+ "license": "ISC",
217
+ "dependencies": {
218
+ "express": "^4.17.2",
219
+ "pug": "^3.0.2",
220
+ "socket.io": "^4.4.1"
221
+ }
222
+ }
223
+ ```
224
+
225
+ 実行すると次のようになります。
226
+ 一人目、二人目は`room1`に追加されます。
227
+ (二人目が追加された時に一人目のウィンドウに二人目のソケットIDも出力されます)
228
+ 三人目は`room2`に追加されます。
229
+
230
+ ```sh
231
+ % node app.js
232
+ Example app listening on port 3000
233
+ connection socket.id: BYCS0K4ZwIzA0HnbAAAB
234
+ join socket.id: BYCS0K4ZwIzA0HnbAAAB, socket.rooms: ["BYCS0K4ZwIzA0HnbAAAB","room1"]
235
+ connection socket.id: 3qos0oYduumeQfBnAAAD
236
+ join socket.id: 3qos0oYduumeQfBnAAAD, socket.rooms: ["3qos0oYduumeQfBnAAAD","room1"]
237
+ connection socket.id: rAIBndZzCigIRUn2AAAF
238
+ join socket.id: rAIBndZzCigIRUn2AAAF, socket.rooms: ["rAIBndZzCigIRUn2AAAF","room2"]
239
+ ```
240
+
241
+ メインウィンドウ
242
+ ![メインウィンドウ](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-31/799a1bc6-2918-4397-9d21-84b080039511.png)
243
+
244
+ 別ウィンドウ一人目
245
+ (二人目が入った後にキャプチャしたため二人目のソケットIDも出力されます。同じルームに追加されたことの確認)
246
+ ![一人目](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-31/c8530918-1a5b-4c01-816b-cd2673d440aa.png)
247
+
248
+ 別ウィンドウ二人目
249
+ ![二人目](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-31/56992ac0-069b-4772-8f27-28d22b9be207.png)
250
+
251
+ 別ウィンドウ三人目
252
+ (三人目はルーム2に追加されます)
253
+ ![三人目](https://ddjkaamml8q8x.cloudfront.net/questions/2022-01-31/175cef8e-0d9a-42f6-b00b-c3ddad104fe1.png)
254
+
255
+ サーバー側で勝手にルームを割り振って良いのか、クライアント側からルームを指定するのか、設計を検討する必要がありそうかな?と思いました。
256
+