how to make a multiple node js chat like facebook?

2019-04-02 09:01发布

well, i have read some tutorials and i have a chat in node js with express and socket io, it works well!! so, the way it works is: a user that opens the url in the port 3000 connects and now cant send messages, if another user connects in the same url and port now can see the new messages an he can send messages too. i want to have multiple scenarios like this in the same app, to make something like facebook chat!!, thanks!

this is the code i have: server side:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){

res.sendFile(__dirname+'/index.html');

});

io.on('connection', function(socket){
console.log('a user connected');

socket.on('chat message', function(msg){
io.emit('chat message', msg);
});


 socket.on('disconnect', function(){
console.log('user disconnected');
});
});



http.listen(3000, function(){
console.log('listening on *:3000');
});

in client side javascript:

 var socket = io();
  $('form').submit(function(){

    socket.emit('chat message', {message: $('#m').val(), type_msg: 'chat_message'});

    $('#m').val('');
    return false;
  });

  socket.on('chat message', function(msg){

   switch(msg.type_msg){
       case "chat_message":
             $('#messages').append($('<li>').text(msg.message));
           break;

        case "user_is_typing":
            $('#status').val(msg.message);
            break;

        case "user_is_not_typing":
           $('#status').val(msg.message);
            break;
       }     
      });


  $('#m').keypress(function(){

    socket.emit('chat message', {message: "User is typing! :D",type_msg: "user_is_writing"});
  });

  $('#m').keyup(function(){

    socket.emit('chat message', {message: "User in thinking...",type_msg: "user_is_typing"});
  });

1条回答
Melony?
2楼-- · 2019-04-02 09:06

I see your code is almost the same as socket.io chat tutorial. First of all, if you want to have a Facebook-like chat, you must think about authenticating users, for which I recommend you to use passport. I recommend you to give a look to this example and, if you have further questions about implementing something like that in your web app, you will find helpful links at the bottom of the README.

Once you have passport implemented, you can use socket.io-passport module (my apologies for not providing a link, but I am not allowed to post more than 2 links with my newbie reputation) to identify which user is triggering each socket connection or, if you want to write a less dependant application, you can write your own logic. For example, you can pass the req.user._id to the client by writing something like this in your routes file:

res.render('yourtemplate.ejs', { userId : req.user._id });

On the client side, you can trigger a kind of handshake event using that id once the page is loaded:

var myId = '<%= userId %>';
socket.emit('handshake', myId);

And, on server side again, listen to that event and act properly:

var userSocket = [];
socket.on('handshake', function (user) {
  if (userSocket[user] === undefined) userSocket[user] = [];
  userSocket[user].push(socket.id);
}

Now you have a two-dimensional array which identifies all sockets used by every user. It allows you to send messages to a certain user:

socket.on('chat message', function (msg) {
  for (var i = 0 ; i < userSocket[msg.to].length ; i++ ) {
    io.to(userSocket[msg.to][i].emit('chat-message', msg);
  }
});

NOTE: As you can see, msg has become an object, not a string. It follows this structure:

{
  from : userId,
  to   : userId,
  text : The message itself
}

This is a very tight guideline, but I think it's enough to give you the idea of what you can do. Of course, you have to append the message to the according DOM element depending of who's sending the message, you have to delete the socket.id on userSocket when an user disconnects, and so on.

I hope it helps!

;)

查看更多
登录 后发表回答