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

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

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

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

Socket.IO

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

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

1回答

378閲覧

Socket.ioをExpressで使いたい

motox

総合スコア3

Node.js

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

Socket.IO

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

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

0グッド

0クリップ

投稿2023/03/30 15:25

実現したいこと

Socket.ioをExpressで作ったプロジェクトに組み込みたい

前提

Express Generatorで作ったプロジェクトのルーターからsocketを使いたい。

マッチング式の1対1の対戦ゲームが作りたいです。あるルーム名を入力するとそこにルームができて、二人がそのルームに入ったらそれ以上は入れないようにし、そのルームの名前の共有で友達と遊べるようにしたいです。

プロジェクトの構造

│ app.js │ ├─bin │ www │ ├─public │ ├─images │ ├─javascripts │ │ singleplayer.js │ │ │ └─stylesheets │ game.css │ style.css │ ├─routes │ index.js │ matching.js │ singleplayer.js │ users.js │ └─views error.ejs index.ejs matching.ejs singleplayer.ejs

ソースコード

matching.js

js

1const express = require('express'); 2const router = express.Router(); 3const app = express(); 4const server = require('http').createServer(app); 5const io = require('socket.io')(server | {serveClient: true}); 6let room = 'aaa' 7 8io.on('connection', (socket) => { 9 console.log('User connected'); 10 11 // Add the user to the room 12 socket.join(room); 13 14 // Notify the user that they have joined the room 15 socket.emit('joined', room); 16}); 17 18router.post('/',(req,res,next) => { 19 console.log("matching..."); 20 room = req.body['room_id']; 21 let data = { 22 title: 'Title', 23 content: room 24 }; 25 res.render('matching',data); 26}); 27 28module.exports = router;

matching.ejs

ejs

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <title><%= title %></title> 5 <link rel='stylesheet' href='/stylesheets/style.css' /> 6 <script src="/socket.io/socket.io.js"></script> 7 <script> 8 const socket = io(); 9 const room = 'aaa'; 10 // When the player joins the room 11 socket.on('joined', (room) => { 12 console.log('Joined room:', room); 13 }); 14 </script> 15</head> 16<body> 17<h1>matching</h1> 18<p><%- content %></p> 19</body> 20</html>

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

エラーメッセージ↓
GET /socket.io/?EIO=4&transport=polling&t=OSp6vHi 404 0.891 ms - 1333
接続できないです;(

教えてほしいこと

どうやったらpostを受け取ったときにsocketを開くか、そもそもそれであっているのか
どうやったら新しいルームみたいな感じのものができるか

初歩的ですが回答お願いします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2023/04/01 08:28

コメントありがとうございます。 (回答へのコメントだと通知が届くのかわからないところもありましたので質問へコメントいたします) > おかげさまでsocketが動くようになったのですが、 良かったです! > もう少し受付してみます 承知しました。 > まだpostのときにどうするかとかよくわかってないので... ちょっと今回の質問内容は漠然とした感じになってしまっていて、 回答する側からすると、どこから回答すれば良いのか悩んでしまい、 結果的に回答がもらえない感じになってしまいそうです。 もししばらく待って、回答がつかないようでしたら、 この質問は「発生している問題・エラーメッセージ」は解消できたみたいですので、 一旦「解決済」にした方が良いかなと思いました。 そして、新たに別の質問をすると良いかなと思いました。 (その際はもう少し質問内容を具体的にすると回答がつきやすくなると思います)
guest

回答1

0

「発生している問題・エラーメッセージ」につきまして

再現確認などしていないためはっきりとはわからないのですが、気になった点を書いてみます。

matching.jsの5行目につきまして、
(const io = require('socket.io')(server | {serveClient: true});)

ドキュメントでは次のようになっていました。
Serverのインスタンスを生成する形です。
このような形にしてみたら何か変わるでしょうか?

js

1const { Server } = require("socket.io"); 2// 省略 3const io = new Server(httpServer, { /* options */ });

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

Expressのルーターモジュールの中でSocket.IOのインスタンスを扱う場合は、
stackoverflowの質問もあったりするようでしたので、躓くところなのかな?という気もしました。
次のリンク先も参照してみると良いかもしれませんね。

https://stackoverflow.com/questions/56405137/node-js-how-to-use-socket-io-in-express-route
https://stackoverflow.com/questions/29334800/express-js-4-and-sockets-with-express-router
https://aaryanadil.com/pass-socket-io-to-express-routes-in-files/

「どうやったらpostを受け取ったときにsocketを開くか、そもそもそれであっているのか」につきまして

サーバー側とクライアント側があるから、(理解するのも、説明するのも、)難しいですよね。

socketを開始するのは、ゲームを開始するときですよね。
サーバー側でPOSTを受け取ったらゲームの画面をクライアントに送るのだと思うのですけど。
Socket.IOを開始するのは、クライアントに送られた画面の中に記述したスクリプトから、がトリガーになると思います。
const socket = io(); の行のことですね。

そうすると、サーバー側の
io.on('connection', (socket) => { })
の中の処理が動きます。
これでSocket.IOのコネクションが確立されるはずです。

まずはここまでがちゃんと動くことを確認した方が良いと思いました。
ルームのことなども考えてしまうと何が問題になっているのか把握するのが大変になってしまうと思いました。

次の「Get started」なども参照してみると良いかもしれませんね。

Get started
https://socket.io/get-started/chat

「どうやったら新しいルームみたいな感じのものができるか」につきまして

Socket.IOでいうルームは質問欄のソースコードでも記述している通り、次のようなコードになると思います。
socket.join(room);
これでプレイヤーがルームに入った感じになると思います。

次の「Rooms」のドキュメントなども参照してみると良いかもしれませんね。

Rooms
https://socket.io/docs/v4/rooms/

Socket.IOのルームとは別に、
アプリとして対戦相手を決めたタイミングで
プレイヤーとプレイヤーをまとめた概念のようなものがあると思います。
サーバー側でPOSTを受け取ったタイミングでroom_idのようなものを参照しているっぽいですが、
このあたりも含めてどのように扱うか、
「設計」する必要があるのかなと思いました。

投稿2023/03/31 00:45

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

motox

2023/03/31 08:05

ご丁寧な回答ありがとうございます!!! おかげさまでsocketが動くようになったのですが、まだpostのときにどうするかとかよくわかってないので... もう少し受付してみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問