0

I've read through this:

https://socket.io/docs/rooms-and-namespaces/#

private chat with socket.io

What I'm trying to do is have a public chat on:

"/"

And a private chat on /xyz, where everyone that's using this URL can talk in.

I'll get to generating random links and figuring them out later, but first I need to figure out how to connect public users and private users to different sockets? Especially since they're doing the same thing I have no idea how to do this efficiently at all.

So firstly I have to catch a server/private URL using:

app.get("/private",function(req,res){
res.render("page");
console.log("Rendered private page"); });

The solution I've thought of first is using a custom namespace.

    var namespace = io.of('/private');
namespace.on('connection',function(socket){
    console.log('someone connected to private');
    socket.emit('pmessage',{message:'Connected to a private chat!'});

});

But this becomes an issue with my frontend(which I know not how to manipulate since I'm very new to this). I'd basically be using duplicate code to handle the same thing, just with different subset of users.

So this:

    var socket = io.connect('127.0.0.1:8090');

I need to add a new socket, right:

    var private = io.connect('127.0.0.1:8090/private');

Then do I just duplicate everything? I know this is probably not the right solution. But I don't know where to turn to. Basically making everything for private instead of socket.

socket.on('message',function(data){
    //Type out the message in the htmlTextField into the htmlChatContent if message was received
    //Keep the other chats
    if(data.message){
        //From w3c:The push() method adds new items to the end of an array, and returns the new length.
        //Example: ["hi","hello"] ---push("wazzzaaap")--->["hi","hello","wazzzaaap"]
        messages.push(data);
        //put messages into the HTML code
        var html = '';
        console.log("Currently in messages" + data.message);
        console.log(data.username);
        for(var i = 0;i<messages.length ;i++){
            //Put it into a string and add a HTML defined symbol sequence for a line break
            //Add username in front of it in bold
            //FIXME: Currently only able to get messages[i] which is just the content
            if(messages[i].username==null){
                html+=messages[i].message + '<br />';
            }
            else{
                html+='<b>'+ messages[i].username + ': </b>' + messages[i].message   + '<br />';

            }

        }
        //Add the message formatted into HTML into the chat content box
        htmlChatContent.innerHTML = html;
        //When sending clear the input field also

        htmlTextField.value = "";
    }
    else{
        //This means there was an error
        //Put error text inside the users text box
        console.log("Error");
        htmlTextField.innerHTML = "There was an sending error!";
    }   
});

I'd appreciate guidance on how to handle randomly generated links, what I've thought of is:

Database of created links, that removes entries the second the last person leaves. However how do I program dynamic links? I can't hardcode 500 different options, right?

Do I need to add more code for the question to be better?

Nephilim
  • 494
  • 5
  • 25

1 Answers1

2

I'll get to generating random links and figuring them out later, but first I need to figure out how to connect public users and private users to different sockets?

No, you need one socket between the client and your server. You can then send data to just some of the aockets from your server. Socket.io got rooms for that, which basically just means that you can manage the sockets in groups and you send data to the sockets in that group easily.

I can't hardcode 500 different [sockets / links], right?

No, that would be overkill. Just let the client / server generate random urls. To make them unique you could just take the timestamp and add a random number:

 const id = "" + Math.floor(Math.random() * 1000) + Date.now();

Now if you want to manage/verify clients on the http server, you could just work with dynamic urls, like:

 yourserver/private/1272271737

With express thats quite easy to catch them all:

 app.get("/private/:id", (req, res) => {
    const { id } = req params;
    // Verify the id and return the clientside code
 });

But actually only the socket server needs to know the rooms id, so you could use so called "hashbang urls", they look like:

 yourserver/private#127272

On the serverside it looks like if the client visits /private so you can just return the application:

 app.get("/private", (req, res) => /*...*/);

But on the clientside you can get the id as:

 const id = location.hash;

Now the client can join the related room:

socket.join(id);

Now when sending a message just send the room id with it:

 socket.emit("msg", id, "Hi!");

On the server, you just broadcast it to that room:

io.on('connection', (socket) => {
  socket.on("msg", (id, msg) => {
    io.to(id).emit("msg", msg);
  });
});
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151