回答編集履歴
1
サンプルアプリのコードを追記しました。
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
|
+

|
243
|
+
|
244
|
+
別ウィンドウ一人目
|
245
|
+
(二人目が入った後にキャプチャしたため二人目のソケットIDも出力されます。同じルームに追加されたことの確認)
|
246
|
+

|
247
|
+
|
248
|
+
別ウィンドウ二人目
|
249
|
+

|
250
|
+
|
251
|
+
別ウィンドウ三人目
|
252
|
+
(三人目はルーム2に追加されます)
|
253
|
+

|
254
|
+
|
255
|
+
サーバー側で勝手にルームを割り振って良いのか、クライアント側からルームを指定するのか、設計を検討する必要がありそうかな?と思いました。
|
256
|
+
|