Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a room id and force two users to join that room?

Im building a chat application in node.js , socket.io and mongoose. My goal is to build a one on one chat, it is similar like facebook web chat. So basically whenever I click on a user it will go to that user url and possibly chat with him/her

But the problem, that I'm facing is that I could only emit the message to the targeted user, but not to myself.

Here's the current code

Serverside

socket.on('chatTo', function(data){
      User.findOne({ username: data.destinationUsername, socketId: { '$ne': null}}, function(err, foundUser) {
        if (foundUser) {
          io.to(foundUser.socketId).emit('incomingChat', { sender: user.username, message: data.message });

        } else {
          io.to(socket.id).emit('deliverError', { error: foundUser + ' is not online' });

        }
      });
    });

Clientside

$(function() {

  var socket = io();


  function chatTo(message, destinationUsername) {
    socket.emit('chatTo', { message: message, destinationUsername });
  }


  $('#sendMessage').submit(function(){
    var input = $('#message').val();
    var username = $('#username').val();
    chatTo(input, username);
    $('#message').val('');
    return false;
  });


  socket.on('incomingChat', function(data) {
    var html = data; // Messages to append to media-list

    $('.media-list').append(html);
  });
});

So what is happening here is that, on the clientside, User A clicks form submit , to submit the message, it will invoke chatTo function and emit the data. Just want to let you guys know, input and username are from html page. It would look something like this

input = "Hello";

username = "jackmoscovi" // user's username

then it will emit both of these data back to server, which is socket.on('chatTo') is listening to. After some MongoDB operation, if found the user then emit to that specific socket.

The result will be

enter image description here

The message that was emitted by batman only shows up on joker's page but not on Batman's page. I know that because I specifically emit to that socket. The real question is How do I force both of these user to be in a unique room? Should I create a new Room mongoose model? and then call socket.join('uniqueRoom')?

and then simply io.to('uniqueRoom').emit("Message?");

How would I implement this room mechanism?

I have been struggling for 2 days already, please someone end this misery :(

like image 875
Jack Moscovi Avatar asked Nov 20 '22 16:11

Jack Moscovi


1 Answers

First create a mongoose schema like this

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;
var messageSchema=new Schema({
    sender : {
        type : String,
    },
    receiver : {
        type : String.
    },
    message : {
        type : String
    }
})
mongoose.model('messages',messageSchema);

Then in server code

message = mongoose.model('messages')
socket.on('chatTo', function(data){  // data is json containing sender, receiver and message
    User.findOne({ username: data.destinationUsername, socketId: { '$ne': null}}, function(err, foundUser) {
        if (foundUser) {
            io.to(foundUser.socketId).emit('incomingChat', { sender: user.username, message: data.message });
            socket.emit('incomingChat', { sender: user.username, message: data.message });
            var newMessage = new message({
                sender : data.sender,
                receiver : data.receiver,
                message : data.message
            })
            newMessage.save(function (err, data){
                if(err)
                    console.log(err)
            })
        } else {
            io.to(socket.id).emit('deliverError', { error: foundUser + ' is not online' });

        }
    });
});
like image 95
Nijeesh Avatar answered Nov 23 '22 13:11

Nijeesh