Обмен сообщениями в приватном чате с использованием Node.js, Socket.io, Redis в PHP

Я работаю над системой обмена личными сообщениями в реальном времени в своем php-приложении. Мои коды работают для всех пользователей вместе. Но мне нужна система обмена личными сообщениями как личное сообщение.

После настройки node и redis я могу получить данные сообщения, которые мне нужны: вот код ::

Внешний интерфейс :: 1. Я использую форму для имени пользователя, сообщения и кнопки отправки.

и уведомления JS:

$( document ).ready(function() {

    var socket = io.connect('http://192.168.2.111:8890');

    socket.on('notification', function (data) {
        var message = JSON.parse(data);
        $( "#notifications" ).prepend("<p> <strong> " + message.user_name + "</strong>: " + message.message + "</p>" );

    });

});

JS на стороне сервера:

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

server.listen(8890);

var users = {};
var sockets = {};

io.on('connection', function (socket) {

    console.log(" New User Connected ");
    // instance of Redis Client
   var redisClient = redis.createClient();
   redisClient.subscribe('notification');

   socket.on('set nickname', function (name) {
       socket.set('nickname', name, function () {
           socket.emit('ready');
       });
   });

  socket.on('msg', function () {
    socket.get('nickname', function (err, name) {
        console.log('Chat message by ', name);
    });
  });


   redisClient.on("message", function(channel, message)
   {
     // to view into terminal for monitoring
     console.log("Message from: " + message + ". In channel: " + channel + ". Socket ID "+ socket.id );

     //send to socket
     socket.emit(channel, message);
   });

   redisClient.on('update_chatter_count', function(data)
   {
      socket.emit('count_chatters', data);
   });

   //close redis
   socket.on('disconnect', function()
   {
      redisClient.quit();
   });

 });

HTML::

<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<form .....>
<input ....... >
</form>
<div id="notifications" ></div>

Общий результат:

John : Hello
Kate : Hi
Others: .....

Вышеуказанные коды прекрасно работают в моем приложении php. Теперь я хочу настроить частную или индивидуальную систему обмена сообщениями.

Как мне нужно добавить имя пользователя или адрес электронной почты или уникальный идентификатор сокета для пользователя. У меня больше нет идей для личных сообщений. Я пытался вычислить в Интернете, но не смог.

** Как мне настроить личное сообщение в моем приложении php? **


person Selim Reza    schedule 16.05.2016    source источник


Ответы (4)


Базовая инициализация переменных:-

В основном создайте MAP из mapOfSocketIdToSocket, а затем отправьте идентификатор конкретного пользователя, которому вы хотите отправить сообщение, из внешнего интерфейса. На сервере найдите объект сокета, сопоставленный с идентификатором пользователя, и отправьте свое сообщение в этот сокет. Вот пример идеи (не полный код)

  var io = socketio.listen(server);
  var connectedCount = 0;
  var clients = [];
  var socketList = [];
  var socketInfo = {};
  var mapOfSocketIdToSocket={};

  socket.on('connectionInitiation', function (user) {
      io.sockets.sockets['socketID'] = socket.id;
      socketInfo = {};
      socketInfo['userId']=user.userId;
      socketInfo['connectTime'] = new Date();
      socketInfo['socketId'] = socket.id;
      socketList.push(socketInfo);

      socket.nickname = user.name;
      socket.userId= user.userId;

      loggjs.debug("<"+ user.name + "> is just connected!!");

      clients.push(user.userId);
      mapOfSocketIdToSocket[socket.id]=socket;
  }
  socket.on('messageFromClient', function (cMessageObj, callback) {
     for(var i=0; i<socketList.length;i++){
       if(socketList[i]['userId']==cMessageObj['messageToUserID']){ // if user is online
        mapOfSocketIdToSocket[socketList[i]['socketId']].emit('clientToClientMessage', {sMessageObj: cMessageObj});
        loggjs.debug(cMessageObj);
      }
    }
  })

Либо вы можете захотеть использовать концепции комнат для частных «один ко многим» или «один к одному» (если только два участника) http://williammora.com/nodejs-tutorial-building-chatroom-with/

person sharif2008    schedule 16.05.2016
comment
пример приложения: justchatnow.herokuapp.com и исходный код github.com/codebazz/justchatnow - person sharif2008; 16.05.2016
comment
:: не работает в личных сообщениях. Я думаю, что я что-то упускаю. Не могли бы вы рассказать мне немного больше, как на стороне сервера, так и на стороне клиента, используя клиент Redis? - person Selim Reza; 17.05.2016
comment
@Мд. Sariful islam Кажется, открытое окно чата, где все пользователи могут отправлять и получать сообщения в одном месте. Но, похоже, это будет система обмена сообщениями один на один. - person naf4me; 17.05.2016
comment
Это не прямое решение. Я просто пытался помочь ему с какой-то идеей. Кто-то может помочь ему - person sharif2008; 17.05.2016
comment
@Мд. Sariful islam :: Я могу сделать для публичного чата, но мне нужно установить приватный как систему обмена сообщениями один на один. Не могли бы вы направить меня? - person Selim Reza; 18.05.2016
comment
Сначала создайте карту user_id=›socket_id и другую socket_id=›user_id на сервере, затем со стороны клиента передайте from_user_id, to_user_id и сообщение на сервер. На сервере повторите эту карту, чтобы получить from_socket_id, to_socket_id, а затем отправьте сообщение в конкретном to_socket_id. Спасибо всем. - person sharif2008; 18.05.2016
comment
@Мд. Шарифул ислам :: Я не тебя. Как я сделал для user_id и partner_id, но не могу сокет для конкретного пользователя... Как я могу получить socket.id для отправителя или получателя? - person Selim Reza; 19.05.2016
comment
да, всегда есть Socket_id, когда пользователь подключен к серверу. Сохраните этот идентификатор сокета и идентификатор пользователя на карте на стороне сервера. Когда сообщение проходит, client_id(user_id) из браузера и на стороне сервера получает соответствующий socket_id из этой карты и передает сообщение в этот сокет. - person sharif2008; 19.05.2016

Я бы предложил вам использовать пространства имен socketIO, это позволяет вам отправлять/испускать события из/в определенные коммуникационные «каналы».

Вот ссылка на документацию socketIO относительно комнат и пространств имен.

http://socket.io/docs/rooms-and-namespaces/

Ваше здоровье

person erwan    schedule 25.05.2016

Одним из решений может быть отправка сообщений человеку с конкретным идентификатором сокета. Поскольку вы уже используете Redis, вы можете сохранить данные пользователя и идентификатор сокета в Redis, когда пользователь присоединяется, а затем отправлять сообщения пользователю, получая идентификатор сокета от Redis, когда вы хотите отправить ему сообщение. События вызова, такие как

socket.emit('отправить приват') из внешнего интерфейса

и на бэкэнде обрабатывать

socket.on('send private'){ // делаем что-то redis внутри этого }

person Avinash    schedule 29.05.2016

Используйте Pusher. Он предлагает использование канала, чтобы сделать возможным приватные чаты без какого-либо дополнительного кода.

person Srirag Nair    schedule 27.05.2016