2011-08-02 85 views
35

我很喜歡socket.io! 文檔太糟糕了,根本不是這樣。使用socket.io發送消息給特定的客戶端,並且使用空消息隊列

我要反饋過socket.io

我的服務器端看起來像這樣發送到特定的客戶端:

app.get('/upload', requiresLogin, function(request, response) { 
    response.render('upload/index.jade'); 
    io.sockets.on('connection', function (socket) { 
     console.log('SOCKET ID ' + socket.id); 
     io.sockets.socket(socket.id).emit('new', 'hello'); 
    }); 
}); 

和客戶端看起來是這樣的:

$(document).ready(function() { 
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js'); 
    socket.on('new', function (data) { 
     console.log(socket.id); 
     console.log(data); 
     //$('#state').html(data.status); 
    }); 
}); 

但客戶完全沒有。我嘗試了幾乎所有的東西。有人能告訴我我做錯了什麼,請! :(

回答

7

2東西

1)你真的應該把你的io.sockets.on(..)app/update路線,以防止添加多個監聽客戶端之外。

2)io.sockets.socket(id);不應該使用它,它應該是socket.emit('new', 'hello')

+0

好吧,這也是一個問題io.connect('http:// localhost:80/socket.io/socket.io.js');但是當我想在上傳過程中發送消息時呢?那麼我需要存儲客戶端ID並使用io.sockets.socket(socket.id).emit('new','hello');或不? –

+0

據我所知,當通過窗體上傳文件時,套接字連接未斷開。 – pkyeck

+0

好,很好,最後一個問題。是否有可能清空消息隊列?當我重新進入視圖,我收到所有的舊按摩... –

52

向特定客戶端發送消息,保存每個連接到對象中的服務器的消息。

var socketio = require('socket.io'); 
var clients = {}; 
var io = socketio.listen(app); 

io.sockets.on('connection', function (socket) { 
    clients[socket.id] = socket; 
}); 

您可以稍後做這樣的事情:

所有的
var socket = clients[sId]; 
socket.emit('show', {}); 
+0

不起作用。我做了一個簡單的測試: var soc; ('connection',function(socket){ \t soc = socket; }); 以外的所有路線。 和比我在我的上傳功能,我已經使用soc.emit('新聞','bla') 沒有任何反應.... –

+0

正如我之前所說:你不能發送事件,而上傳文件。但是這種方法可以工作,並且當你有相應的ID時,你可以發送消息給特定的客戶端。 – pkyeck

+0

: - /抱歉我誤解了你。所以沒有辦法通過路由功能來觸發特定客戶端的消息? –

2

首先,你不能在客戶端使用socket.id

,然後更改線

var socket = io.connect('http://localhost:80/socket.io/socket.io.js');

var socket = io.connect('http://localhost:80/');

18

一對夫婦的方式來過socket.io將反饋發送到特定的客戶端包括:

  • 正如p kyeck,所有客戶端保存到一個對象,這樣你就可以在你的路線處理後發送給這些特定的客戶,如:

    var sessionsConnections = {}; 
    sio.on('connection', function (socket) { 
        // do all the session stuff 
        sessionsConnections[socket.handshake.sessionID] = socket; 
    }); 
    
  • ,或者使用socket.io的內置的房間支持 - 訂閱每個客戶的房間連接和路由處理程序中通過這個房間發送,例如:

    sio.on('connection', function (socket) { 
        // do all the session stuff 
        socket.join(socket.handshake.sessionID); 
        // socket.io will leave the room upon disconnect 
    }); 
    
    app.get('/', function (req, res) { 
        sio.sockets.in(req.sessionID).send('Man, good to see you back!'); 
    }); 
    

致謝:

http://www.danielbaulig.de/socket-ioexpress/#comment-1158

請注意,這兩個示例解決方案都假定socket.io和express已配置爲使用相同的會話存儲,因此會引用相同的會話對象。見鏈接的上方和下方對實現這一目標的詳細信息:

https://github.com/LearnBoost/socket.io/wiki/Authorizing

+0

只是想說,使用會話ID作爲一個房間是一個很好的建議。幫助我解決了我遇到的一個問題,所以謝謝:) –

+2

看起來像socket.io 1.0已經內置支持每個插座的方法:http://socket.io/docs/rooms-and-namespaces/ –

+0

房間應該照顧集羣。將套接字像其他答案一樣保存在本地內存中可能導致內存泄漏並且無法擴展。 – tsuz

5

在socket.io 1.0,這是它是如何工作的。它可能適用於較低版本,但我無法保證。

socket.to(socket_id_here).emit('new', 'hello'); 

這是可行的,因爲socket.io會自動將一個套接字添加到連接套接字ID的房間。另外,如果你打算升級到1.0版本,那麼對api有很多改變,所以你有時必須修改一些代碼才能在1.0中工作。

0

我相信io.sockets.socket已被刪除,並在Socket.IO(https://github.com/socketio/socket.io/issues/1618)中出現問題。

您可以使用io.sockets.connected [socket.id]和存儲通過用戶名與用戶參考socket.id:

var usernames = {}; 
usernames[username] = socket.id; 
// Sending the message 
io.sockets.connected[usernames[username]].emit(...); 

我沒有看到它在文檔上的任何地方,所以我可以看到這是怎麼回答的。另外,如果您沒有任何通過用戶名的參考,您可以嘗試:

users[socket.id] = socket.id; 

複製密鑰和值以便於訪問。

也有可能通過使用io.clients的另一種方式,如下所述,但我沒有使用該方法。

其他的解決辦法:Send message to specific client with socket.io and node.js

4

在Socket.io 1.0+做到這一點,正確的方法是:

io.to(users_socket_id).emit('new', 'hello'); 

您也可以爲「users_socket_id」發射到特定的插座替換房間名.io房間。

0

您是否嘗試過使用?

var socket = io.connect('http://localhost:80/'); 
+0

這個答案已經由Shekhar給出了幾個答案 –

0

我累了節點的最新版本,並socket.io 下面我要去發佈完整的代碼

<ul id="messages"></ul> 
<form action=""> 
    <input id="id1" /><button>Send</button> 
</form> 
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script> 
<script src="http://code.jquery.com/jquery-1.11.1.js"></script> 
<script> 

    var io = io.connect(); 
    $('form').submit(function(){ 
    io.emit('drumevent', $('#id1').val()); 
    $('#id1').val(''); 
    return false; 
    }); 
    io.on('drumevent', function(msg){ 
    console.log(msg); 



    $('#messages').append($('<li></li>').text(msg.message+' quantity = '+msg.quantity)); 
    }); 
</script> 

服務器端代碼

var usernames = {};io.on('connection', function(socket){usernames["username"] = socket.id; 
socket.on('drumevent', function(msg){  
var socketId = socket.id;io.to(socketId).emit('drumevent', data); 
相關問題