[javascript] How to send a message to a particular client with socket.io

I'm starting with socket.io + node.js, I know how to send a message locally and to broadcast socket.broadcast.emit() function:- all the connected clients receive the same message.

Now, I would like to know how to send a private message to a particular client, I mean one socket for a private chat between 2 person (Client-To-Client stream). Thanks.

This question is related to javascript jquery ajax node.js socket.io

The answer is


You can use socket.io rooms. From the client side emit an event ("join" in this case, can be anything) with any unique identifier (email, id).

Client Side:

var socket = io.connect('http://localhost');
socket.emit('join', {email: [email protected]});

Now, from the server side use that information to create an unique room for that user

Server Side:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('join', function (data) {
    socket.join(data.email); // We are using room of socket io
  });
});

So, now every user has joined a room named after user's email. So if you want to send a specific user a message you just have to

Server Side:

io.sockets.in('[email protected]').emit('new_msg', {msg: 'hello'});

The last thing left to do on the client side is listen to the "new_msg" event.

Client Side:

socket.on("new_msg", function(data) {
    alert(data.msg);
}

I hope you get the idea.


SURE: Simply,

This is what you need :

io.to(socket.id).emit("event", data);

whenever a user joined to the server, socket details will be generated including ID. This is the ID really helps to send a message to particular people.

first we need to store all the socket.ids in array,

var people={};

people[name] =  socket.id;

here name is the receiver name. Example:

people["ccccc"]=2387423cjhgfwerwer23;

So, now we can get that socket.id with the receiver name whenever we are sending message:

for this we need to know the receivername. You need to emit receiver name to the server.

final thing is:

 socket.on('chat message', function(data){
io.to(people[data.receiver]).emit('chat message', data.msg);
});

Hope this works well for you.

Good Luck!!


As the az7ar answer is beautifully said but Let me make it simpler with socket.io rooms. request a server with a unique identifier to join a server. here we are using an email as a unique identifier.

Client Socket.io

socket.on('connect', function () {
  socket.emit('join', {email: [email protected]});
});

When the user joined a server, create a room for that user

Server Socket.io

io.on('connection', function (socket) {
   socket.on('join', function (data) {    
    socket.join(data.email);
  });
});

Now we are all set with joining. let emit something to from the server to room, so that user can listen.

Server Socket.io

io.to('[email protected]').emit('message', {msg: 'hello world.'});

Let finalize the topic with listening to message event to the client side

socket.on("message", function(data) {
  alert(data.msg);
});

The reference from Socket.io rooms


In a project of our company we are using "rooms" approach and it's name is a combination of user ids of all users in a conversation as a unique identifier (our implementation is more like facebook messenger), example:

|id | name |1 | Scott |2 | Susan

"room" name will be "1-2" (ids are ordered Asc.) and on disconnect socket.io automatically cleans up the room

this way you send messages just to that room and only to online (connected) users (less packages sent throughout the server).


Here is the full solution for Android Client + Socket IO Server (Lot of code but works). There seems to be lack of support for Android and IOS when it comes to socket io which is a tragedy of sorts.

Basically creating a room name by joining user unique id from mysql or mongo then sorting it (done in Android Client and sent to server). So each pair has a unique but common amongst the pair room name. Then just go about chatting in that room.

For quick refernce how room is created in Android

 // Build The Chat Room
        if (Integer.parseInt(mySqlUserId) < Integer.parseInt(toMySqlUserId)) {
            room = "ic" + mySqlUserId + toMySqlUserId;
        } else {
            room = "ic" + toMySqlUserId + mySqlUserId;
        }

The Full Works

Package Json

"dependencies": {
    "express": "^4.17.1",
    "socket.io": "^2.3.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.6"
  }

Socket IO Server

app = require('express')()
http = require('http').createServer(app)
io = require('socket.io')(http)

app.get('/', (req, res) => {

    res.send('Chat server is running on port 5000')
})

io.on('connection', (socket) => {

    // console.log('one user connected ' + socket.id);

    // Join Chat Room
    socket.on('join', function(data) {

        console.log('======Joined Room========== ');
        console.log(data);

        // Json Parse String To Access Child Elements
        var messageJson = JSON.parse(data);
        const room = messageJson.room;
        console.log(room);

        socket.join(room);

    });

    // On Receiving Individual Chat Message (ic_message)
    socket.on('ic_message', function(data) {
        console.log('======IC Message========== ');
        console.log(data);

        // Json Parse String To Access Child Elements
        var messageJson = JSON.parse(data);
        const room = messageJson.room;
        const message = messageJson.message;

        console.log(room);
        console.log(message);

        // Sending to all clients in room except sender
        socket.broadcast.to(room).emit('new_msg', {
            msg: message
        });

    });

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

});

http.listen(5000, () => {

    console.log('Node app is running on port 5000')
})

Android Socket IO Class

public class SocketIOClient {

    public Socket mSocket;

    {
        try {
            mSocket = IO.socket("http://192.168.1.5:5000");
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public Socket getSocket() {
        return mSocket;
    }
}

Android Activity

public class IndividualChatSocketIOActivity extends AppCompatActivity {

    // Activity Number For Bottom Navigation Menu
    private final Context mContext = IndividualChatSocketIOActivity.this;

    // Strings
    private String mySqlUserId;
    private String toMySqlUserId;

    // Widgets
    private EditText etTextMessage;
    private ImageView ivSendMessage;

    // Socket IO
    SocketIOClient socketIOClient = new SocketIOClient();
    private String room;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        // Widgets
        etTextMessage = findViewById(R.id.a_chat_et_text_message);
        ivSendMessage = findViewById(R.id.a_chat_iv_send_message);

        // Get The MySql UserId from Shared Preference
        mySqlUserId = StartupMethods.getFromSharedPreferences("shared",
                                                              "id",
                                                              mContext);

        // Variables From Individual List Adapter
        Intent intent = getIntent();

        if (intent.hasExtra("to_id")) {

            toMySqlUserId = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras())
                                                          .get("to_id"))
                                   .toString();
        }

        // Build The Chat Room
        if (Integer.parseInt(mySqlUserId) < Integer.parseInt(toMySqlUserId)) {
            room = "ic" + mySqlUserId + toMySqlUserId;
        } else {
            room = "ic" + toMySqlUserId + mySqlUserId;
        }

        connectToSocketIO();

        joinChat();

        leaveChat();

        getChatMessages();

        sendChatMessages();

    }

    @Override
    protected void onPause() {
        super.onPause();

    }

    private void connectToSocketIO() {

        socketIOClient.mSocket = socketIOClient.getSocket();
        socketIOClient.mSocket.on(Socket.EVENT_CONNECT_ERROR,
                                  onConnectError);
        socketIOClient.mSocket.on(Socket.EVENT_CONNECT_TIMEOUT,
                                  onConnectError);
        socketIOClient.mSocket.on(Socket.EVENT_CONNECT,
                                  onConnect);
        socketIOClient.mSocket.on(Socket.EVENT_DISCONNECT,
                                  onDisconnect);
        socketIOClient.mSocket.connect();
    }

    private void joinChat() {

        // Prepare To Send Data Through WebSockets
        JSONObject jsonObject = new JSONObject();

        // Header Fields
        try {

            jsonObject.put("room",
                           room);

            socketIOClient.mSocket.emit("join",
                                        String.valueOf(jsonObject));

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    private void leaveChat() {
    }

    private void getChatMessages() {

        socketIOClient.mSocket.on("new_msg",
                                  new Emitter.Listener() {
                                      @Override
                                      public void call(Object... args) {
                                          try {
                                              JSONObject messageJson = new JSONObject(args[0].toString());
                                              String message = String.valueOf(messageJson);

                                              runOnUiThread(new Runnable() {
                                                  @Override
                                                  public void run() {
                                                      Toast.makeText(IndividualChatSocketIOActivity.this,
                                                                     message,
                                                                     Toast.LENGTH_SHORT)
                                                           .show();
                                                  }
                                              });
                                          } catch (JSONException e) {
                                              e.printStackTrace();
                                          }
                                      }
                                  });
    }

    private void sendChatMessages() {

        ivSendMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = etTextMessage.getText()
                                              .toString()
                                              .trim();

                // Prepare To Send Data Thru WebSockets
                JSONObject jsonObject = new JSONObject();

                // Header Fields
                try {
                    jsonObject.put("room",
                                   room);

                    jsonObject.put("message",
                                   message);

                    socketIOClient.mSocket.emit("ic_message",
                                                String.valueOf(jsonObject));

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        });
    }

    public Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(IndividualChatSocketIOActivity.this,
                                   "Connected To Socket Server",
                                   Toast.LENGTH_SHORT)
                         .show();

                }
            });

            Log.d("TAG",
                  "Socket Connected!");
        }
    };

    private Emitter.Listener onConnectError = new Emitter.Listener() {
        @Override
        public void call(Object... args) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                }
            });
        }
    };
    private Emitter.Listener onDisconnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                }
            });
        }
    };

}

Android Gradle

// SocketIO
implementation ('io.socket:socket.io-client:1.0.0') {
    // excluding org.json which is provided by Android
    exclude group: 'org.json', module: 'json'
}

You can refer to socket.io rooms. When you handshaked socket - you can join him to named room, for instance "user.#{userid}".

After that, you can send private message to any client by convenient name, for instance:

io.sockets.in('user.125').emit('new_message', {text: "Hello world"})

In operation above we send "new_message" to user "125".

thanks.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to ajax

Getting all files in directory with ajax Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource Fetch API request timeout? How do I post form data with fetch api? Ajax LARAVEL 419 POST error Laravel 5.5 ajax call 419 (unknown status) How to allow CORS in react.js? Angular 2: How to access an HTTP response body? How to post a file from a form with Axios

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to socket.io

WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 WebSockets and Apache proxy : how to configure mod_proxy_wstunnel? node.js TypeError: path must be absolute or specify root to res.sendFile [failed to parse JSON] Socket.io + Node.js Cross-Origin Request Blocked Node.js: socket.io close client connection How to send a message to a particular client with socket.io Socket.IO handling disconnect event Get connection status on Socket.io client Which websocket library to use with Node.js? Maximum concurrent Socket.IO connections