将更新的数据广播到通过socket.io连接到nodejs服务器的所有客户端

我有一个应用程序,我正在写,需要能够更新所有连接的客户端,每当客户端通过ajax请求连接到本地套接字服务器,并更新系统。 处理请求是好的,但发送来自本地套接字服务器的响应到socket.io广播给大家是我有一个问题。 我确定这是简单的,我在这里看,但是这对我来说是非常新的,所以我有问题,特别是与asynchronous编程的思维方式。 下面是我正在努力完成的一个简短的版本,以及我在哪里徘徊。

var express = require('express'), http = require('http'), net = require('net'), app = express(), server = http.createServer(app), io = require('socket.io').listen(server); app.get("/execute", function (req, res) { // connect to local socket server var localSock = net.createConnection("10000","127.0.0.1"); localSock.setEncoding('utf8'); localSock.on('data', function(data) { // send returned results from local socket server to all clients do stuff here to data ... send data to all connected clients view socketio socket... var dataToSend = data; localSock.end(); }).on('connect', function(data) { // send GET data to local socket server to execute var command = req.query["command"]; localSock.write(command); }); app.get (..., function() {}); app.get (..., function() {}); server.listen('3000'); io.on('connection', function(client) { client.broadcast.send(dataToSend); }); 

全局套接字对象被引用为io.sockets 。 因此,要全局广播,只需将数据传递给io.sockets.emit() ,并将其发送给所有客户端,而不pipe命名空间如何。

你发布的代码,假设你的意思是io.sockets.on

 io.on('connection', function(client) { client.broadcast.send(dataToSend); }); 

正在侦听任何连接到任何名称空间,并且一旦build立连接,就向所有客户端广播dataToSend 。 由于您的主要目标是将数据发送给所有人,因此您只需使用全局名称空间io.sockets ,但在代码中使用的方式不起作用。

 app.get('/execute', function (req, res) { var localSock = net.createConnection("10000","127.0.0.1"); localSock.setEncoding('utf8'); localSock.on('connect', function(data) { var command = req.query.command; localSock.write(command); }); localSock.on('data', function(data) { var dataToSend = data; localSock.end(); }); }); 

在这部分代码中,您正在正确侦听path/execute GET请求,但是您的套接字逻辑不正确。 你正在写连接的command ,这很好,但你假设data事件意味着数据stream已经结束。 由于stream有事件end ,你需要收集data事件的响应,最后对数据做一些处理;

例如,如果服务器发送stringThis is a string that is being streamed. 你要使用:

 localSock.on('data', function(data) { var dataToSend = data; localSock.end(); }); 

您可能只会收到This is a stri ,然后过早地closures与end()的套接字。 相反,你会想这样做:

 var dataToSend = []; localSock.on('data', function(data) { dataToSend.push(data); }); localSock.on('end', function() { dataToSend = dataToSend.join(''); io.sockets.emit(dataToSend); }); 

请注意,在这种情况下,您不需要使用end()因为remove服务器将发送它自己的FIN数据包。

我想问你用net.Socket做什么,因为返回的数据是Readable Stream ,这意味着当你监听data事件时,数据可能是必须收集的完整响应的片段直到end事件被解雇。 如果你想要发送一个消息到一个socket.io服务器,那么你可以使用socket.io-client ,socket.io自己的客户端。

这里是一个非常stream行的webtutorial的一些代码。 为了使用Express 3.x进行了一些更改。

这里是app.js的代码:

  var express = require('express') , http = require('http'); var app = express(); var server = http.createServer(app); var io = require('socket.io').listen(server); server.listen(8000); // routing app.get('/', function (req, res) { res.sendfile(__dirname + '/index.html'); }); // usernames which are currently connected to the chat var usernames = {}; io.sockets.on('connection', function (socket) { // when the client emits 'sendchat', this listens and executes socket.on('sendchat', function (data) { // we tell the client to execute 'updatechat' with 2 parameters io.sockets.emit('updatechat', socket.username, data); }); // when the client emits 'adduser', this listens and executes socket.on('adduser', function(username){ // we store the username in the socket session for this client socket.username = username; // add the client's username to the global list usernames[username] = username; // echo to client they've connected socket.emit('updatechat', 'SERVER', 'you have connected'); // echo globally (all clients) that a person has connected socket.broadcast.emit('updatechat', 'SERVER', username + ' has connected'); // update the list of users in chat, client-side io.sockets.emit('updateusers', usernames); }); // when the user disconnects.. perform this socket.on('disconnect', function(){ // remove the username from global usernames list delete usernames[socket.username]; // update list of users in chat, client-side io.sockets.emit('updateusers', usernames); // echo globally that this client has left socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected'); }); }); 

obove代码与webtutorial中的代码相同,只是使用Riwels的答案对Express 3.x进行了一些更改。

这里是index.html的代码:

  <script src="/socket.io/socket.io.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> <script> var socket = io.connect('http://localhost:8000'); // on connection to server, ask for user's name with an anonymous callback socket.on('connect', function(){ // call the server-side function 'adduser' and send one parameter (value of prompt) socket.emit('adduser', prompt("What's your name?")); }); // listener, whenever the server emits 'updatechat', this updates the chat body socket.on('updatechat', function (username, data) { $('#conversation').append('<b>'+username + ':</b> ' + data + '<br>'); }); // listener, whenever the server emits 'updateusers', this updates the username list socket.on('updateusers', function(data) { $('#users').empty(); $.each(data, function(key, value) { $('#users').append('<div>' + key + '</div>'); }); }); // on load of page $(function(){ // when the client clicks SEND $('#datasend').click( function() { var message = $('#data').val(); $('#data').val(''); // tell server to execute 'sendchat' and send along one parameter socket.emit('sendchat', message); }); // when the client hits ENTER on their keyboard $('#data').keypress(function(e) { if(e.which == 13) { $(this).blur(); $('#datasend').focus().click(); } }); }); </script> <div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;"> <b>USERS</b> <div id="users"></div> </div> <div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;"> <div id="conversation"></div> <input id="data" style="width:200px;" /> <input type="button" id="datasend" value="send" /> </div>