2011-11-27 86 views
8

這裏有2個相關的問題。將它們放在一起更有意義。使用socket.io創建連接客戶端的列表

問題1

我有一個Node.js的應用程序,它發出事件給所有客戶,所有現有客戶將與ready EMIT迴應。我如何創建所有回覆初始排放的客戶列表,以及可以使用哪種標識來區分客戶?

問題2:

我所試圖做後收集連接的客戶名單,是再訪問N行數的MySQL數據庫表,並指定每個客戶端的每個X行。這些行將被髮回到它們各自的客戶端。如何才能做到這一點?

現行規範QN 1

節點代碼

setInterval(function() { 
    util.log('Checking for new jobs...'); 
    dbCheckQueue(function(results) { // checks if there are new rows to "distribute" to clients 
     if (results.length) { 
      util.log(results.length + ' new jobs found.'); 
      io.sockets.emit('job_available'); 
     } 
    }); 
}, 10*1000); 

客戶端JS代碼

socket.on('job_available', function() { 
       console.log('Job Available.. Responding with Ready!'); 
       socket.emit('ready'); 
      }); 

io.sockets.on('connection', function(socket) { 
    socket.on('ready', function() { 
     // UPDATE N rows with client_id in column checkout. 
     // Then SELECTS * from table where checkout = client_id 
     getListings(client_id, function(listings) { 
      socket.emit('job', listings); // send jobs 
     }); 
    }); 
}); 

現行規範的Qn2 該代碼適用於單個客戶端,但是如何遍歷所有連接的客戶端並執行相同的列更新和行選擇?

io.sockets.on('connection', function(socket) { 
    socket.on('ready', function() { 
     // UPDATE N rows with client_id in column checkout. 
     // Then SELECTS * from table where checkout = client_id 
     getListings(client_id, function(listings) { 
      socket.emit('job', listings); // send jobs 
     }); 
    }); 
}); 

回答

16

您需要自己跟蹤連接的客戶端。最簡單的方法做到這一點是使用數組:

var clients = []; 

io.sockets.on('connect', function(client) { 
    clients.push(client); 

    client.on('disconnect', function() { 
     clients.splice(clients.indexOf(client), 1); 
    }); 
}); 

然後,你可以參考該clients陣列的服務器上你需要的地方,在你ready事件處理程序或什麼的。喜歡的東西:

io.sockets.on('connection', function(socket) { 
    socket.on('ready', function() { 
     // UPDATE N rows with client_id in column checkout. 
     // Then SELECTS * from table where checkout = client_id 
     clients.forEach(function(client, index) { 
      var client_id = index; // Just use the index in the clients array for now 
      getListings(client_id, function(listings) { 
       socket.emit('job', listings); // send jobs 
      }); 
     }); 
    }); 
}); 
+0

你可以提出一個getListings()函數的邏輯,因爲我應用了相似的解決方案,但我在屏幕上看到一個名稱爲第一個登錄用戶。 – johannesMatevosyan

+0

'getListings'調用只是我從原始問題中提取的示例代碼。我不知道它包含了什麼或者它是如何實現的。 – rossipedia

+0

我明白了,因爲我存儲客戶陣列,當我嘗試用'foreach'或'for'環路我單單隻出現在客戶端的瀏覽器的用戶名的第一個記錄的HEPL檢索。 – johannesMatevosyan

19

Socket.io爲您提供了一個公共API對於這一點,所以不是黑客的東西像布萊恩建議你可以使用:

io.sockets.clients() 

這將返回所有連接的陣列客戶端。

如果你想連接到某個命名空間的所有客戶端:

io.of('/namespace').clients() 

但是,如果你想在一個房間所有插座,你甚至可以將其過濾更..:

io.sockets.clients('room name here as first argument') 

將返回一個連接的房間數組room name here as first argument

+0

謝謝3rdEden,我用Bryan的稍作修改的方案,因爲我只想要以'ready'消息回答那些連接的客戶端被推入的陣列。可以使用API​​以不同的方式做一些事情嗎? – Nyxynyx

+0

實際上,使用api稍微黑客會更好,你所要做的只是像socket.isReady = true;準備當收到由,你會從mantaining另一個列表中保存自己:P – ShrekOverflow

+0

這是要走的路!謝謝:) –

相關問題