admin管理员组文章数量:1131224
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.
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.
Share Improve this question edited Nov 22, 2013 at 4:35 Sangram Singh 7,19115 gold badges51 silver badges79 bronze badges asked Jul 4, 2013 at 18:22 Nizar B.Nizar B. 3,1189 gold badges41 silver badges56 bronze badges 7- 1 Sorry psiphi75 but this link doesn't reply to my answer, isn't a duplicate question. – Nizar B. Commented Jul 5, 2013 at 4:13
- 2 @psiphi75, it's no way a duplicate – softvar Commented Oct 12, 2013 at 14:34
- 1 Can't stand people like @psiphi. Are you even a developer? How does an HTML5 specific question relate to a standalone library? And for what it's worth, WebSockets are NOT Socket.io. Socket.io is a library that can USE WebSockets, but I digress. This is also a more specific question relating to the library about sending data to only specific clients, not about the technology itself. – Levi Roberts Commented Jun 25, 2015 at 2:31
- Possible duplicate of Send message to specific client with socket.io and node.js – bugwheels94 Commented Jul 3, 2017 at 16:27
- @bugwheels94 Not really, this post is from 2011 and since nodejs had loads of changes code-wise. this post is definitely a valid question/answer for this issue. – Nizar B. Commented Jul 3, 2017 at 16:50
8 Answers
Reset to default 328You 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.
When a user connects, it should send a message to the server with a username which has to be unique, like an email.
A pair of username and socket should be stored in an object like this:
var users = {
'[email protected]': [socket object],
'[email protected]': [socket object],
'[email protected]': [socket object]
}
On the client, emit an object to the server with the following data:
{
to:[the other receiver's username as a string],
from:[the person who sent the message as string],
message:[the message to be sent as string]
}
On the server, listen for messages. When a message is received, emit the data to the receiver.
users[data.to].emit('receivedMessage', data)
On the client, listen for emits from the server called 'receivedMessage', and by reading the data you can handle who it came from and the message that was sent.
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!!
You can refer to socket.io rooms.
When you handshaked socket - you can join them 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.
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).
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
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'
}
Instead of making rooms (as you only want to send the message to 1 person) what I did was make an in-memory array:
clientSessions: Map<string, UserIdentifier> = new Map()
I did it this way for my use-case where I want to get the socket ID I want based on an identifier I set. The key in the map will be the identifier I set, and the value includes the ID of that socket connected. See server-side code below.
Client-side:
const socket = io('http://localhost:3200', {query: {randomKeyID: '123'}});
Server-side:
handleDisconnect(client: Socket) {
const query = client.handshake.query;
const randomKeyID = <string> query.randomKeyID
this.clientSessions.delete(randomKeyID);
console.log(`Client disconnected: ${client.id}`);
}
handleConnection(client: Socket, ...args: any[]) {
const query = client.handshake.query;
const user: UserIdentifier = {
id: client.id,
randomKeyID: <string> query.randomKeyID
}
this.clientSessions.set(user.randomKeyID, user);
console.log(`Client connected: ${client.id}`);
}
Added this in server-side as well to easily access the websocket (type Server is from socket.io):
@WebSocketServer()
server: Server;
So, if I want to send to a particular client, I can:
const { randomKeyID } = this.clientSessions.get(something);
this.server.to(randomKeyID).emit('clientListener', 'Hello');
本文标签: javascriptHow to send a message to a particular client with socketioStack Overflow
版权声明:本文标题:javascript - How to send a message to a particular client with socket.io - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736756843a1951334.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论