1

I would like to create dynamic room by the server and personalize the URL like this: localhost:3000/path/path.php?roomId.

I have a form for the user to enter their name, then they click a submit button "create a room" and they will enter a page with this type of url : " localhost:3000/path/path.php?roomId " where roomId is created by the server when the button is clicked.

For the moment when I create a room I just have the URL " localhost:3000/path/path.php " but I would like to personalize the URL so it becomes localhost:3000/path/path.php?roomId

The idea behind it is to be able to then share the link localhost:3000/path/path.php?roomId to other users so they can directly join the room only by clicking on the shared link (the code is for a multi player game, so I would like to create a shareable url and unique link like for the game skribbl.io).

However; I only see tutorials where the user enters the name of the room so I don't know how to approach this problem.

Here is my code : server.js

const express = require('express');
const app = express();
const httpServer = require('http').createServer(app);
const { getRandomString } = require("../utils/utils");

const io = require("socket.io")(httpServer, {
  cors: {
    optionSuccesStatus: 200,
    origin: "http://localhost",
    methods: ["GET", "POST"],
    credentials: true,
  }
});
//tbh I don't really understand all those lines, I just got it by following lots of tutorials
app.set('views', '../../path.php');
app.set('view engine', 'php');
app.use(express.urlencoded({ extended: true }));

io.on('connection', client => {

  //Creation private room
  client.on('createRoom', () => {
    var roomId = getRandomString(7); // use a function to create a random code room
    console.log("player joined");
    client.join(roomId);
  });
}

client.js :

const socket = io(document.location.protocol+'//'+document.location.host +":3000");

socket.emit('createRoom');

the form page.php :

<form id = "formulaire_creation_jeu" method='POST' action="path.php">
    <div id="pseudo" class='form-group mb-6'>
         <label for="username" class='form-label inline-block mb-2 text-gray-700'>Pseudo</label>
         <input id="username" type='text' name="username" required minlength="2" maxlength="15" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
                        class='form-control block w-full px-3 py-1.5 text-base font-normal text-gray-700 bg-white bg-clip-padding border border-solid border-gray-300 transition ease-in-out focus:text-gray-700 focus:bg-white focus:border-black focus:outline-none'>
          <div id="error_container_pseudo"></div>
     </div>    
     <div>
          <button type="submit" class="inline-block px-6 py-2.5 bg-yellow-400 text-black font-medium text-xs font-serif leading-tight uppercase rounded shadow-md hover:bg-yellow-500 hover:shadow-lg focus:bg-yellow-500 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-yellow-500 active:shadow-lg transition duration-150 ease-in-out">
              Create a room
          </button>  
     </div>
</form>

With my following code, when I submit my form, I just have a link like this : localhost:3000/path/path.php . The server and client are connected but I am not sure it even created a room. Thank you in advance for your help

  • There is examples in the docs: https://socket.io/docs/v4/rooms/ – Lawrence Cherone Jun 28 '22 at 10:46
  • Thank you for your answer, I have already checked the official documentation but as a beginner I don't really understand it. It doesn't explain how it is linked to the client. In the link you gave me they wrote in io.on('connection') just socket.join('a room'), but how does the client emit this ? – chubby marschmallow Jun 28 '22 at 10:52

1 Answers1

1

So the only thing you want is for the roomId to be generated server-side - I don't see what would prevent you from emitting this on the client-side:

const socket = io(document.location.protocol+'//'+document.location.host +":3000");
socket.emit('createRoom');

And then on the server-side:

io.on('connection', client => {

  // Create private room
  client.on('createRoom', ({roomId}) => {
    console.log("Player wants to create a room");
    client.join(getRandomString(7));
  });
}

The only difference is that I moved the getRandomString(7) from the client to the server.

  • Thank you for your answer, I thought I had to put a parameter (here is roomId) but indeed when I just do client.on('createRoom', () => it now works, thank you. But I still dont have the path that I want. I have localhost:3000/path/path.php instead of localhost:3000/path/path.php?roomId I will edit my post because I didn't well explained my problem – chubby marschmallow Jun 28 '22 at 11:58
  • 1
    Okay, I would suggest you reply back from the server with a callback, like in the following documentation: [Callbacks](https://socket.io/docs/v4/emitting-events/#acknowledgements) In essence, you pass a function from your frontend to the server; the server then creates a room, and invokes your callback with the roomId supplied as a parameter, and it is run on your client. But can I ask - is it really important for you to generate the id of these rooms on the server-side? What's the use case? – Rasmus Edvardsen Jun 28 '22 at 12:29
  • Great :) Once again, I'd urge you to question whether generating the `roomId` is really necessary to be done on the server, as it introduces **potentially** needless complexity in to your system. – Rasmus Edvardsen Jun 28 '22 at 12:45
  • So would it be better if I do it like I did originally in the client side ? However if I do that, the callback doesn't work anymore. – chubby marschmallow Jun 28 '22 at 12:55
  • I don't know what your use case is, but it **could** be simpler. Let's take some of these online games, like **skribbl.io** or **kahoot.it**, for an example. Usually what happens is that someone "hosts" the game, and they then share a link to their friends, right? Here, I don't think there's anything wrong with creating the `roomId` client-side, seeing as the room is created regardless, and for friends to join their host-friend, they just need to put in some code. – Rasmus Edvardsen Jun 28 '22 at 12:58
  • I would like to do like skribbl.io, I also thought about asking user to enter a code to join a room but I thought it would be more convenient for users to just click an url and join friends to play. However if what I want to do is too complicated I will do the code solution. – chubby marschmallow Jun 28 '22 at 13:06
  • So when you press **create private room** for skribbl.io, it will generate a **code** (or **roomId** if you will) for your **room**, and then a link with that **code** appended to it, something like so: `https://skribbl.io/some-generic-code` or `https://skribbl.io?code=some-generic-code` So when a user goes to skribbl.io, and your browser sees that it has an extra path, or an extra query parameter, it will try to join a room with that specific **code**. For this, it is perfectly fine to initialise the room on the client. – Rasmus Edvardsen Jun 28 '22 at 13:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/245980/discussion-between-chubby-marschmallow-and-rasmus-edvardsen). – chubby marschmallow Jun 28 '22 at 13:23