質問編集履歴

1

ソースコード、説明の追記

2020/06/21 10:20

投稿

kohaku
kohaku

スコア11

test CHANGED
File without changes
test CHANGED
@@ -83,3 +83,347 @@
83
83
  );
84
84
 
85
85
  ```
86
+
87
+
88
+
89
+ 試したソースコードを追記いたします。
90
+
91
+ 最初に記述したソースコードがエラーになってしまい、申し訳ございませんでした。
92
+
93
+
94
+
95
+ ```node
96
+
97
+ 'use strict';
98
+
99
+
100
+
101
+ // モジュール
102
+
103
+ const express = require( 'express' );
104
+
105
+ const http = require( 'http' );
106
+
107
+ const socketIO = require( 'socket.io' );
108
+
109
+
110
+
111
+ // オブジェクト
112
+
113
+ const app = express();
114
+
115
+ const server = http.Server( app );
116
+
117
+ const io = socketIO( server );
118
+
119
+
120
+
121
+ // 定数
122
+
123
+ const PORT = process.env.PORT || 8080;
124
+
125
+ const SYSTEMNICKNAME = '**system**';
126
+
127
+
128
+
129
+ // 関数
130
+
131
+ // 数字を2桁の文字列に変換
132
+
133
+ const toDoubleDigitString =
134
+
135
+ ( num ) =>
136
+
137
+ {
138
+
139
+ return ( "0" + num ).slice( -2 ); // slice( -2 )で後ろから2文字取り出す。
140
+
141
+ };
142
+
143
+
144
+
145
+ // 時刻文字列の作成(書式は「YY/DD/MM hh:mm ss」)
146
+
147
+ const makeTimeString =
148
+
149
+ ( time ) =>
150
+
151
+ {
152
+
153
+ return toDoubleDigitString( time.getFullYear() ) + '/' + toDoubleDigitString( time.getMonth() + 1 ) + '/' + toDoubleDigitString( time.getDate() )
154
+
155
+ + ' ' + toDoubleDigitString( time.getHours() ) + ':' + toDoubleDigitString( time.getMinutes() ) + ' ' + toDoubleDigitString( time.getSeconds() );
156
+
157
+ }
158
+
159
+
160
+
161
+ // グローバル変数
162
+
163
+ let iCountUser = 0; // ユーザー数
164
+
165
+
166
+
167
+ /* 処理を管理するためのフラグ */
168
+
169
+ let onceFlag = true; // ボタンの状態
170
+
171
+
172
+
173
+ // 接続時の処理
174
+
175
+ // ・サーバーとクライアントの接続が確立すると、
176
+
177
+ //  サーバー側で、'connection'イベント
178
+
179
+ //  クライアント側で、'connect'イベントが発生する
180
+
181
+ io.on(
182
+
183
+ 'connection',
184
+
185
+ ( socket ) =>
186
+
187
+ {
188
+
189
+ console.log( 'connection' );
190
+
191
+
192
+
193
+ let strNickname = ''; // コネクションごとで固有のニックネーム。イベントをまたいで使用される。
194
+
195
+
196
+
197
+ // 切断時の処理
198
+
199
+ // ・クライアントが切断したら、サーバー側では'disconnect'イベントが発生する
200
+
201
+ socket.on(
202
+
203
+ 'disconnect',
204
+
205
+ () =>
206
+
207
+ {
208
+
209
+ console.log( 'disconnect' );
210
+
211
+
212
+
213
+ if( strNickname )
214
+
215
+ {
216
+
217
+ // ユーザー数の更新
218
+
219
+ iCountUser--;
220
+
221
+
222
+
223
+ // メッセージオブジェクトに現在時刻を追加
224
+
225
+ const strNow = makeTimeString( new Date() );
226
+
227
+
228
+
229
+ // システムメッセージの作成
230
+
231
+ const objMessage = {
232
+
233
+ strNickname: SYSTEMNICKNAME,
234
+
235
+ strMessage: strNickname + ' left.' + " there are " + iCountUser + " participants",
236
+
237
+ strDate: strNow
238
+
239
+ }
240
+
241
+
242
+
243
+ // 送信元含む全員に送信
244
+
245
+ io.emit( 'spread message', objMessage );
246
+
247
+ }
248
+
249
+ } );
250
+
251
+
252
+
253
+ // 入室時の処理
254
+
255
+ // ・クライアント側のメッセージ送信時の「socket.emit( 'join', strNickname );」に対する処理
256
+
257
+ socket.on(
258
+
259
+ 'join',
260
+
261
+ ( strNickname_ ) =>
262
+
263
+ {
264
+
265
+ console.log( 'joined :', strNickname_ );
266
+
267
+
268
+
269
+ // コネクションごとで固有のニックネームに設定
270
+
271
+ strNickname = strNickname_;
272
+
273
+
274
+
275
+ // ユーザー数の更新
276
+
277
+ iCountUser++;
278
+
279
+
280
+
281
+ // メッセージオブジェクトに現在時刻を追加
282
+
283
+ const strNow = makeTimeString( new Date() );
284
+
285
+
286
+
287
+ // システムメッセージの作成
288
+
289
+ const objMessage = {
290
+
291
+ strNickname: SYSTEMNICKNAME,
292
+
293
+ strMessage: strNickname + ' joined.' + " there are " + iCountUser + " participants",
294
+
295
+ strDate: strNow
296
+
297
+ }
298
+
299
+
300
+
301
+ // 送信元含む全員に送信
302
+
303
+ io.emit( 'spread message', objMessage );
304
+
305
+ } );
306
+
307
+
308
+
309
+ // 新しいメッセージ受信時の処理
310
+
311
+ // ・クライアント側のメッセージ送信時の「socket.emit( 'new message', $( '#input_message' ).val() );」に対する処理
312
+
313
+ socket.on(
314
+
315
+ 'new message',
316
+
317
+ ( strMessage ) =>
318
+
319
+ {
320
+
321
+ console.log( 'new message', strMessage );
322
+
323
+
324
+
325
+ // 現在時刻の文字列の作成
326
+
327
+ const strNow = makeTimeString( new Date() );
328
+
329
+
330
+
331
+ // メッセージオブジェクトの作成
332
+
333
+ const objMessage = {
334
+
335
+ strNickname: socket.id,
336
+
337
+ strMessage: strMessage,
338
+
339
+ strDate: strNow
340
+
341
+ }
342
+
343
+
344
+
345
+ // 送信元含む全員に送信
346
+
347
+ //io.emit( 'spread message', strMessage );
348
+
349
+ io.emit( 'spread message', objMessage );
350
+
351
+ } );
352
+
353
+
354
+
355
+ /* 一度しか行わせたくない */
356
+
357
+ socket.on(
358
+
359
+ 'once',
360
+
361
+ () =>
362
+
363
+ {
364
+
365
+ if(onceFlag) {
366
+
367
+ console.log('once');
368
+
369
+ }
370
+
371
+ } );
372
+
373
+ } );
374
+
375
+
376
+
377
+ // 公開フォルダの指定
378
+
379
+ app.use( express.static( __dirname + '/public' ) );
380
+
381
+
382
+
383
+ // サーバーの起動
384
+
385
+ server.listen(
386
+
387
+ PORT,
388
+
389
+ () =>
390
+
391
+ {
392
+
393
+ console.log( 'Server on port %d', PORT );
394
+
395
+ } );
396
+
397
+ ```
398
+
399
+
400
+
401
+ クライアント側ではjqueryを用いてソースコードを用意して、onceのidを付けたdivタグを用意しておりました。
402
+
403
+ ```javascript
404
+
405
+ $("#once").on(
406
+
407
+ 'click',
408
+
409
+ () =>
410
+
411
+ {
412
+
413
+ socket.emit('once');
414
+
415
+ }
416
+
417
+ );
418
+
419
+ ```
420
+
421
+
422
+
423
+ 上のイベントが発火したときに「once」のログが1度だけ残り、以後はクリックしてもログが残らないことは確認しております。
424
+
425
+ しかし、ほぼ同時に起こった場合はあくまで推測でしかなく、試せてない状況です。申し訳ございません。
426
+
427
+
428
+
429
+ すみません、よろしくお願いいたします。