質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Pug

Pug(旧Jade)とは、HTMLを書くためのテンプレートエンジン。タグで囲む必要がないなど記述を省略できるため、HTMLの記述が簡単になります。ファイル分割も可能で、変数やループなど便利な機能も備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Q&A

解決済

1回答

1260閲覧

別ウィンドウで同じ画面を共有しながらroom機能を使って共有人数を二人までという制限をかけたい。

mariko68311

総合スコア10

Pug

Pug(旧Jade)とは、HTMLを書くためのテンプレートエンジン。タグで囲む必要がないなど記述を省略できるため、HTMLの記述が簡単になります。ファイル分割も可能で、変数やループなど便利な機能も備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

0グッド

0クリップ

投稿2022/01/26 15:21

私は現在Node.jsとpugを中心にボードゲームを作成しているのですが、
ネット上での対戦環境を整えるにむけて、
socket.ioをサーバーのjsファイルとプレイ画面のpugファイルに組み込もうと思っていたのですが、どのサイトを参考にして組み込もうとしてもうまくいきませんでした。
いきなりネットでの対戦を可能にするのは難しいと考えているので、
とりあえずタイトルのとおりの別ウィンドウで見た際に同じ画面が共有されていて、それが共有される人数が二人までという制限をかけるところまでを実現したいので、誰かご教授願えないでしょうか?

実現したいこと

サーバーのjsファイルとプレイ画面のpugファイルにsocket.ioを組み込み、
別ウィンドウで見た際に同じ画面が共有されていて、それが共有される人数が二人までという制限をかけたい。
おそらくなのですが、駒の位置情報を送信しないといけないので、barrとwarrの情報を呼び出したい。
タイミングとしてはプレイ画面の前にあるポップアップのスタートボタンを押すとサーバーが接続される、という感じにしたい。
ポップアップに関してはない方が都合がいいのなら消しても大丈夫で、その場合はプレイ画面がに遷移した瞬間がいいです。
プログラムを書くために使っているのはVisual Studio Codeです。

発生している問題・エラーメッセージ

下記に記述したサイトを参考にしてプログラムを組み込もうとしても修正前と何も変わらない。おそらく打ち込んだプログラムが完全にスルーされている。読み込んでいないということでエラーメッセージもログも何も出てこないので何がどう間違っているという判別もつけられない。

該当のソースコード

現在は下記に書いたyoutubeの動画を5分あたりまでを参考にしてこのようなプログラムになっています。
明らかに関係ない部分は省いています。

pug

1#startpop 2 .pop-star 3 p#startcom スタート 4script. 5 const startcom = document.getElementById('startcom'); 6 7 startcom.addEventListener('click', () => { 8 startpop.style.display='none'; 9 socket.emit('buttonPressed', clientRoom); 10 }); 11 12 var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; 13 var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; 14 15script. 16 const socket = io(); 17 18 let clientRoom; 19 20 socket.on('serverMsg', (data) => { 21 console.log(`I should be in room No.${data}`); 22 clientRoom = data; 23 }); 24 25 socket.on('switchFromServer', () => { 26 console.log(`koko`); 27 });

js

1const express = require("express"); 2const app = express(); 3const port = 3001; 4const server = app.listen(port); 5const socketio = require("socket.io"); 6const io = socketio(server); 7 8app.set("view engine", "pug"); 9app.use(express.static(`${__dirname}/public`)); 10 11let clientNo = 0; 12 13io.on('connection', (socket) => { 14 clientNo++; 15 socket.join(Math.round(clientNo/2)); 16 socket.emit('serverMsg', Math.round(clientNo/2)); 17 18 socket.join(barr); 19 socket.join(warr); 20 socket.emit('serverMsg', barr); 21 socket.emit('serverMsg', warr); 22 23 socket.on('buttonPressed', clientRoom =>{ 24 io.to(clientRoom).emit('switchFromServer'); 25 }) 26});

試したこと

socket.join(barr);
socket.join(warr);
socket.emit('serverMsg', barr);
socket.emit('serverMsg', warr);
の部分をpugファイルに書き込んでみても何も変化が起きず、
pugファイルの二つあるscript文を一つにまとめようとするとポップアップのスタートを押せなくなってしまった。

補足情報

参考にしたサイトです。
https://www.youtube.com/watch?v=0zTY73khJPM&t=238s
https://atmarkit.itmedia.co.jp/ait/articles/1603/14/news015_2.html
https://kazzstorage.com/websocket-reversi-dev/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/01/28 08:50

まだ回答がついていないようでしたのでコメントしてみます。 > 修正前と何も変わらない。おそらく打ち込んだプログラムが完全にスルーされている。 > pugファイルの二つあるscript文を一つにまとめようとするとポップアップのスタートを押せなくなってしまった。 変わらないのか、押せなくなってしまった(変わった)のか、状況が正しく把握できませんでした・・ 「スルーされている」の状況をもう少し具体的にご記載いただくと良いかもしれません。 > 下記に記述したサイトを参考にしてプログラムを組み込もうとしても修正前と何も変わらない。おそらく打ち込んだプログラムが完全にスルーされている。読み込んでいないということでエラーメッセージもログも何も出てこないので何がどう間違っているという判別もつけられない。 「修正前」というのは参考にしたサイトの通りに作った状態でしょうか? この状態では動くのが確認できているということですかね。 一旦、この状態に戻した方が良いのかもしれません。 `socket.join(barr);`のように、サーバー側でクライアント側の変数を使おうとしてしまっているようですので、 サーバーか、クライアントか、どちらかを意識して少しずつ修正していくのが良さそうに思いました。 https://socket.io/docs/v4/server-api https://socket.io/docs/v4/client-api
mariko68311

2022/01/29 16:54

回答ありがとうございます!えっとですね、最初のふたつの件に関しては参考サイトのプログラムを利用しても修正前、つまりsocket.ioのプログラムを入れる前と動きが変わらない、ということです。後、その入れたsocket.ioのプログラムを無理やり1つのscript文に書き込んだ結果、そもそも進行不可になってしまったので、この書き方自体が間違っているだなと思い、発生している問題ではなく、試したことの方で書かせてもらいました。
mariko68311

2022/01/29 16:56

2つ目の件についてなのですが、上でも話したのですが修正前はプログラムを入れる前を指しているので、参考サイトの通りに入れた状態は修正後になっちゃいます、読みづらくて申し訳ないです、、、
mariko68311

2022/01/29 16:58

joinってクライアント側の変数だったんですね!理解が薄いまま使ってたもので、、、公式のサイトを2種類載せてくれていますが、具体的にどこが使えそう!というのは今載せている情報でわかったりしますか、?分からないなら分からないでも大丈夫です、その時はまた自分でこの2つのサイトからヒントを得られないか探してみますので、!
guest

回答1

0

ベストアンサー

コメントありがとうございます。

修正前はプログラムを入れる前を指しているので、

修正前というのは、Socket.IOに関する処理を入れる前という意味だったのですね。
一旦、Socket.IOに関する処理は全て元に戻して、まず、Socket.IOの接続(connection)が確立できるところを目指すのが良いと思いました。

サーバー側

app.listenしてしまうと動作しないそうですので、引用したコードを参考にExpressにおけるSocket.IOのサーバー側の初期化をします。
createServerしたものを使うイメージのようです。

js

1const express = require("express"); 2const { createServer } = require("http"); 3const { Server } = require("socket.io"); 4 5const app = express(); 6const httpServer = createServer(app); 7const io = new Server(httpServer, { /* options */ }); 8 9io.on("connection", (socket) => { 10 console.log(socket.id); 11}); 12 13httpServer.listen(3000);

CAUTION
Using app.listen(3000) will not work here, as it creates a new HTTP server.
(app.listen(3000) を使用すると、新しい HTTP サーバーが作成されるため、ここでは動作しません。)

https://socket.io/docs/v4/server-initialization/#with-express

クライアント側

クライアント側でSocket.IOの初期化(io())をしていますが、クライアント側のSocket.IOのライブラリーは読み込みされていますでしょうか?
していない場合は次の引用を参考にライブラリーを読み込みます。
(Pugのコードに記載がないようでしたので念の為確認させていただきました)

(HTMLの場合)

html

1<script src="https://cdn.socket.io/4.4.1/socket.io.min.js" integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H" crossorigin="anonymous"></script>

(Pugの場合)

pug

1script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous")

https://socket.io/docs/v4/client-installation/

それからクライアント側のSocket.IOを初期化します。

js

1const socket = io(); 2socket.on("connect", () => { 3 console.log(socket.id); 4});

https://socket.io/docs/v4/client-initialization/#from-the-same-domain

ここまで実装するとサーバー側とクライアント側の接続が確立されるはずです。
(クライアント側のio()が実行されて、サーバー側のio.on("connection", () => {})が動くはずです)
そして、Expressを起動したターミナルにソケットのidが出力されるはずです。
ブラウザーのコンソールにも同じidが出力されるはずです。


joinってクライアント側の変数だったんですね!

すみません、、joinメソッドのことではなく、barrwarr変数がクライアント側で定義されているもので、それをサーバー側で使ってしまっている、という意味で書きました。
joinメソッドはサーバー側のAPIで、ソケットをルームに追加するためのもののようですね。

socket.join(room)
Adds the socket to the given room or to the list of rooms.
(ソケットを指定されたルームまたはルームのリストに追加します。)
https://socket.io/docs/v4/server-api/#socketjoinroom


接続が確立できたら、次はソケットをルームに追加するところですかね。
(まだデータの共有とかは考えない方が良いと思います)

ブラウザーからボタンをクリックした時にルームに追加するのか、
ページを読み込んだ時に(ボタンをクリックする前に)ルームに追加するのか、
混乱してしまっているように見えましたので、
それらを整理した上で少しずつ記述すると良いと思いました。

追記

追記です。
最小限のサンプルアプリを書いてみました。
読んだだけでは理解できないところもあると思いますので、面倒でもご自身で一度動かしてみることが大切かな?と思います。
ショートカットしようとすると後でそのツケを払うことになり、結果的に遠回りになってしまう、というのが個人的な経験則です・・

js

1// app.js 2const express = require("express") 3const { createServer } = require("http") 4const { Server } = require("socket.io") 5 6const app = express() 7const httpServer = createServer(app) 8const io = new Server(httpServer, { /* options */ }) 9const port = 3000 10 11app.set("view engine", "pug") 12 13app.get("/", (req, res) => { 14 res.render("index", { title: "Hey", message: "Hello there!" }) 15}) 16 17app.get("/window1", (req, res) => { 18 res.render("window1") 19}) 20 21const socketPerRoom = 2 22let socketCount = 0 23 24io.on("connection", (socket) => { 25 console.log(`connection socket.id: ${socket.id}`) 26 socket.on("join", () => { 27 socketCount++ 28 const room = `room${Math.ceil(socketCount / socketPerRoom)}` 29 // ソケットをルームに追加する 30 socket.join(room) 31 console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) 32 // ルーム全体に送信する(最大2つのソケット) 33 io.to(room).emit("joined", socket.id, room) 34 }) 35}) 36 37httpServer.listen(port, () => { 38 console.log(`Example app listening on port ${port}`) 39})

.

pug

1//- views/index.pug 2html 3 head 4 title= title 5 body 6 h1= message 7 input(type="button", value="join", id="button1") 8 script. 9 window.addEventListener("DOMContentLoaded", () => { 10 const button1 = document.querySelector("#button1") 11 button1.addEventListener("click", () => { 12 //- 別ウィンドウで開く(Socket.IOの接続は別ウィンドウで) 13 window.open("/window1", "_blank") 14 }) 15 })

.

pug

1//- views/window1.pug 2html 3 head 4 title= "Window1" 5 script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") 6 body 7 h1= "Window1" 8 ul(id="ul1") 9 script. 10 window.addEventListener("DOMContentLoaded", () => { 11 //- Socket.IO接続 12 const socket = io() 13 socket.on("connect", () => { 14 //- 接続した時のイベント 15 //- ソケットのIDをコンソールと画面のリストに出力する 16 console.log(`connect: ${socket.id}`) 17 const li1 = document.createElement('li') 18 li1.textContent = `connect socket.id: ${socket.id}` 19 const ul1 = document.querySelector("#ul1") 20 ul1.append(li1) 21 }) 22 socket.on("disconnect", () => { 23 console.log(`disconnect: ${socket.id}`) 24 }) 25 socket.on("joined", (socketId, room) => { 26 //- ルームに追加した時のイベント 27 //- ルームに追加されたソケットのIDとルームの名前をコンソールと画面のリストに出力する 28 console.log(`joined socketId: ${socketId}, room: ${room}`) 29 const li1 = document.createElement('li') 30 li1.textContent = `joined socketId: ${socketId}, room: ${room}` 31 const ul1 = document.querySelector("#ul1") 32 ul1.append(li1) 33 }) 34 //- サーバーに送信する(ルームに追加するためのイベント) 35 socket.emit("join") 36 })

.

json

1// package.json 2{ 3 "name": "sample", 4 "version": "1.0.0", 5 "description": "", 6 "main": "app.js", 7 "scripts": { 8 "test": "echo \"Error: no test specified\" && exit 1" 9 }, 10 "author": "", 11 "license": "ISC", 12 "dependencies": { 13 "express": "^4.17.2", 14 "pug": "^3.0.2", 15 "socket.io": "^4.4.1" 16 } 17}

実行すると次のようになります。
一人目、二人目はroom1に追加されます。
(二人目が追加された時に一人目のウィンドウに二人目のソケットIDも出力されます)
三人目はroom2に追加されます。

sh

1% node app.js 2Example app listening on port 3000 3connection socket.id: BYCS0K4ZwIzA0HnbAAAB 4join socket.id: BYCS0K4ZwIzA0HnbAAAB, socket.rooms: ["BYCS0K4ZwIzA0HnbAAAB","room1"] 5connection socket.id: 3qos0oYduumeQfBnAAAD 6join socket.id: 3qos0oYduumeQfBnAAAD, socket.rooms: ["3qos0oYduumeQfBnAAAD","room1"] 7connection socket.id: rAIBndZzCigIRUn2AAAF 8join socket.id: rAIBndZzCigIRUn2AAAF, socket.rooms: ["rAIBndZzCigIRUn2AAAF","room2"]

メインウィンドウ
メインウィンドウ

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

別ウィンドウ二人目
二人目

別ウィンドウ三人目
(三人目はルーム2に追加されます)
三人目

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

投稿2022/01/30 05:26

編集2022/01/31 14:44
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mariko68311

2022/01/31 00:08

返信遅くなりました!確かにいろいろ焦ってしまっていたのかもしれませんね、、、 言われた通り、一度最初からsocket.ioの書き込みをやり直してみます!また進展があったらお聞きします!ただまだベストアンサーには選べません、ごめんなさい、(他の質問で完全に解決していないのにえらんではだめだと怒られてしまったので)
退会済みユーザー

退会済みユーザー

2022/01/31 03:34

ご丁寧にコメントありがとうございます。 プロフィールから過去の質問を見ましたが、今回の質問は一連の流れの中の最後の質問だったのですね。 それを把握したら、今回の質問に対する回答も適切じゃない気がしてきましたので、後で修正・追記しようと思います。 (過去の受付中の質問も回答できそうでしたら回答してみようと思います)
mariko68311

2022/02/02 02:22

おお、とても助かっています!また少しずつ進めているので、わからないところがあったらよろしくお願いします!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問