socket.io 및 node.js를 사용하여 특정 클라이언트에게 메시지 보내기
socket.io 및 node.js로 작업하고 있으며 지금까지는 꽤 좋아 보이지만 서버에서 특정 클라이언트로 메시지를 보내는 방법을 모르겠습니다.
client.send(message, receiverSessionId)
그러나 방법
.send()
이나
.broadcast()
방법 모두 내 필요를 제공 하지 않는 것 같습니다.가능한 해결책으로 찾은 것은
.broadcast()
메서드가 메시지를 보내지 않는 SessionId 배열을 두 번째 매개 변수로 받아들이므로 그 순간에 연결된 모든 SessionId가있는 배열을 서버에 전달할 수 있다는 것입니다. 메시지를 보내길 원하지만 더 나은 해결책이 있어야한다고 생각합니다.어떤 아이디어?
글쎄, 당신은 (놀람)에 대한 클라이언트를 잡아야합니다, 당신은 간단한 길을 갈 수 있습니다 :
var io = io.listen(server);
io.clients[sessionID].send()
어느 것이 깨질 지 의심 스럽지만 항상
io.clients
변경 될 가능성이 있으므로 위의 내용을주의해서 사용하십시오.또는 클라이언트를 직접 추적하므로 리스너
clients
에서 자신의 객체에 클라이언트를 추가하고
connection
리스너에서 제거하십시오
disconnect
.응용 프로그램에 따라 클라이언트에 더 많은 상태를 원할 수 있으므로 후자를 사용하므로
clients[id] = {conn: clientConnect, data: {...}}
작업을 수행 할 수 있습니다.
Ivo Wetzel의 답변이 Socket.io 0.9에서 더 이상 유효하지 않은 것 같습니다.요컨대 이제를 저장하고 메시지를 보내는 데
socket.id
사용해야
io.sockets.socket(savedSocketId).emit(...)
합니다.이것이 클러스터 Node.js 서버에서 작동하는 방법입니다.먼저 메시지가 교차 프로세스로 이동할 수 있도록 Redis 저장소를 저장소로 설정해야합니다.
var express = require("express");
var redis = require("redis");
var sio = require("socket.io");
var client = redis.createClient()
var app = express.createServer();
var io = sio.listen(app);
io.set("store", new sio.RedisStore);
// In this example we have one master client socket
// that receives messages from others.
io.sockets.on('connection', function(socket) {
// Promote this socket as master
socket.on("I'm the master", function() {
// Save the socket id to Redis so that all processes can access it.
client.set("mastersocket", socket.id, function(err) {
if (err) throw err;
console.log("Master socket is now" + socket.id);
});
});
socket.on("message to master", function(msg) {
// Fetch the socket id from Redis
client.get("mastersocket", function(err, socketId) {
if (err) throw err;
io.sockets.socket(socketId).emit(msg);
});
});
});
클러스터링 코드를 생략했습니다. 왜냐하면 더 복잡하기 때문이지만 추가하기는 쉽지 않습니다. 작업자 코드에 모든 것을 추가하십시오. 더 많은 문서는 여기
http://nodejs.org/api/cluster.html
각 소켓은 이름에 대한 소켓 ID로 회의실에 참여하므로
io.to(socket#id).emit('hey')
문서 :
http://socket.io/docs/rooms-and-namespaces/#default-room
건배
가장 단순하고 가장 우아한 솔루션
다음과 같이 쉽습니다.
client.emit("your message");
그리고 그게 다야.
그러나 어떻게? 예를 들어주세요
우리 모두가 필요로하는 것은 실제로 완전한 예이며, 그것이 따르는 것입니다. 이것은 가장 최근의 socket.io 버전 (2.0.3)으로 테스트되었으며 최신 Javascript도 사용하고 있습니다 (지금 우리 모두가 사용해야합니다).
The example is comprised of two parts: a server and a client. Whenever a client connects, it starts receiving from the server a periodic sequence number. A new sequence is started for each new client, so the server has to keep track of them individually. That's where the "I need to send a message to a particular client" comes into play. The code is very simple to understand. Let's see it.
Server
server.js
const
io = require("socket.io"),
server = io.listen(8000);
let
sequenceNumberByClient = new Map();
// event fired every time a new client connects:
server.on("connection", (socket) => {
console.info(`Client connected [id=${socket.id}]`);
// initialize this client's sequence number
sequenceNumberByClient.set(socket, 1);
// when socket disconnects, remove it from the list:
socket.on("disconnect", () => {
sequenceNumberByClient.delete(socket);
console.info(`Client gone [id=${socket.id}]`);
});
});
// sends each client its current sequence number
setInterval(() => {
for (const [client, sequenceNumber] of sequenceNumberByClient.entries()) {
client.emit("seq-num", sequenceNumber);
sequenceNumberByClient.set(client, sequenceNumber + 1);
}
}, 1000);
The server starts listening on port 8000 for incoming connections. When one arrives, it adds that new client to a map so it can keep track of its sequence number. It also listens for that client's disconnect
event, when it'll remove it from the map.
Each and every second, a timer is fired. When it does, the server walks through the map and sends a message to every client with its current sequence number. It then increments it and stores the number back in the map. That's all that is to it. Easy peasy.
Client
The client part is even simpler. It just connects to the server and listens for the seq-num
message, printing it to the console every time it arrives.
client.js
const
io = require("socket.io-client"),
ioClient = io.connect("http://localhost:8000");
ioClient.on("seq-num", (msg) => console.info(msg));
Running the example
Install the required libraries:
npm install socket.io
npm install socket.io-client
Run the server:
node server
Open other terminal windows and spawn as many clients as you want by running:
node client
I have also prepared a gist with the full code here.
In 1.0 you should use:
io.sockets.connected[socketid].emit();
You can use
//send message only to sender-client
socket.emit('message', 'check this');
//or you can send to all listeners including the sender
io.emit('message', 'check this');
//send to all listeners except the sender
socket.broadcast.emit('message', 'this is a message');
//or you can send it to a room
socket.broadcast.to('chatroom').emit('message', 'this is the message to all');
Whatever version we are using if we just console.log() the "io" object that we use in our server side nodejs code, [e.g. io.on('connection', function(socket) {...});], we can see that "io" is just an json object and there are many child objects where the socket id and socket objects are stored.
I am using socket.io version 1.3.5, btw.
If we look in the io object, it contains,
sockets:
{ name: '/',
server: [Circular],
sockets: [ [Object], [Object] ],
connected:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
here we can see the socketids "B5AC9w0sYmOGWe4fAAAA" etc. So, we can do,
io.sockets.connected[socketid].emit();
Again, on further inspection we can see segments like,
eio:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
So, we can retrieve a socket from here by doing
io.eio.clients[socketid].emit();
Also, under engine we have,
engine:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
So, we can also write,
io.engine.clients[socketid].emit();
So, I guess we can achieve our goal in any of the 3 ways I listed above,
- io.sockets.connected[socketid].emit(); OR
- io.eio.clients[socketid].emit(); OR
- io.engine.clients[socketid].emit();
You can do this
On server.
global.io=require("socket.io")(server);
io.on("connection",function(client){
console.log("client is ",client.id);
//This is handle by current connected client
client.emit('messages',{hello:'world'})
//This is handle by every client
io.sockets.emit("data",{data:"This is handle by every client"})
app1.saveSession(client.id)
client.on("disconnect",function(){
app1.deleteSession(client.id)
console.log("client disconnected",client.id);
})
})
//And this is handle by particular client
var socketId=req.query.id
if(io.sockets.connected[socketId]!=null) {
io.sockets.connected[socketId].emit('particular User', {data: "Event response by particular user "});
}
And on client, it is very easy to handle.
var socket=io.connect("http://localhost:8080/")
socket.on("messages",function(data){
console.log("message is ",data);
//alert(data)
})
socket.on("data",function(data){
console.log("data is ",data);
//alert(data)
})
socket.on("particular User",function(data){
console.log("data from server ",data);
//alert(data)
})
io.sockets.sockets[socket.id].emit(...) worked for me in v0.9
As of version 1.4.5, be sure you provide a properly prefixed socketId in io.to(). I was taking the socketId the Client logged to debug and it was without prefix so I ended up searching forever till I found out! So you might have to do it like this if the Id you have is not prefixed:
io.to('/#' + socketId).emit('myevent', {foo: 'bar'});
Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.
This might help: http://socket.io/docs/rooms-and-namespaces/
'programing' 카테고리의 다른 글
Ruby on Rails 콜백, : before_save와 : before_create의 차이점은 무엇입니까? (0) | 2020.05.21 |
---|---|
폴더가 있는지 확인하는 방법 (0) | 2020.05.21 |
ExpressJS-처리되지 않은 오류 이벤트 발생 (0) | 2020.05.21 |
INSTALL_FAILED_DUPLICATE_PERMISSION… C2D_MESSAGE (0) | 2020.05.21 |
UIImageView의 UIGestureRecognizer (0) | 2020.05.21 |