2013-05-03 66 views
1

我有一個應用程序,我正在寫這個應用程序需要能夠在客戶端通過ajax請求連接到本地套接字服務器時更新所有連接的客戶端,更新系統。處理請求是好的,但從本地套接字服務器發送到socket.io的響應廣播給每個人都是我遇到問題的地方。我確信這是我看過來的簡單東西,但這對我來說很新,所以我遇到了問題,特別是異步編程思維方式。下面是我想要完成的一個簡短版本,以及我在哪裏徘徊。廣播更新數據到所有通過socket.io連接到nodejs服務器的客戶端

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); 
}); 
+0

在向套接字服務器執行'.write()'之後,嘗試調用'io.emit('commandExecuted',dataToSend)',它應該向連接到'socket.io'服務器的所有客戶端發出事件。該代碼片段看起來有點不完整.. – Gntem 2013-05-03 15:52:09

+0

在執行寫入命令並在localSock.on('data',function(data){}中處理該數據之後,我不想在額外的處理之前將它發送給客戶端已經完成了。 – 2013-05-03 16:38:07

回答

1

全局插座對象爲io.sockets引用。因此,要進行全局廣播,只需將數據傳遞到io.sockets.emit(),並將其發送給所有客戶端,而不管命名空間如何。

,您張貼,假設你的意思是io.sockets.on代碼:

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

用於監聽到任何命名空間的任何連接,以及廣播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(); 
    }); 

}); 

在代碼中的這一部分,你是正確的監聽路徑/executeGET請求,但您的插座邏輯是不正確的。您正在編寫command立即連接,這很好,但您認爲data事件意味着數據流已結束。由於該流有事件end,因此您希望收集具有data事件的響應,然後最後對end上的數據進行處理;

例如,如果服務器發送的字符串This is a string that is being streamed.和你使用:

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

你可能只能收到This is a stri,然後過早地end()關閉套接字。相反,你會想這樣做:

var dataToSend = []; 

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

注意,在這種情況下,你不需要使用end()因爲刪除服務器將發送它自己的FIN包。

我想請你和net.Socket做什麼,因爲返回的數據是Readable Stream,這意味着,當你聽的data事件,該數據可能是必須充分反應的碎片收集,直到end事件被解僱。如果你想要發送消息給socket.io服務器,那麼你可以使用socket.io自己的客戶端socket.io-client

0

這是一些非常受歡迎的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只用了answer of Riwels做了一些改變了快遞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> 
相關問題