1

我是 Node.js 的新手,我正在编写一个客户端来使用来自服务器的基于文本的 TCP 流。出于测试目的,我想在 Node 中模拟服务器,这样我就可以在没有其他依赖项的情况下进行测试。

我有一个捕获的数据文件,如下所示:

$X,... <-- broadcast every second 
$A,...
$A,...
$B,...
$X,... <-- broadcast every second 
$A,...
$A,...
$C,...
$X,...  <-- broadcast every second 

服务器每秒发出一条以 $X 开头的行。其他记录在事件发生时广播。如何修改下面的网络服务器以广播此数据并对其进行限制,使其一次发出一行并在每次遇到以 $X 开头的行时暂停一秒钟?

到目前为止,这是我的代码,它读取数据并通过端口广播它:

 var http = require('http')
 , fs = require('fs')
;
var server = http.createServer(function (req, res) {
 var stream = fs.createReadStream(__dirname + '/data.txt');
 stream.pipe(res);
});
server.listen(8000);
console.log('server running on 8000');

这可行,但显然只是以扭曲的速度流出整个文件。我想要的是吐出从一个 $X 到下一个 $X 的所有行,暂停一秒钟(足够接近以进行测试),然后继续到下一个 $X 等等,例如:

> telnet 127.0.0.1 8000
$X,... 
$A,...
$A,...
$B,...

(output would pause for one second)

$X,...
$A,...
$A,...
$C,...

(output would pause for one second)

$X,...
...

在上面的示例中,当我与客户端连接时,广播总是从 data.txt 的开头开始。理想情况下,该服务器将继续循环广播此数据,允许客户端随时断开连接并重新连接,并在服务器模拟器当前所在的任何位置开始接收数据。

(PS - data.txt 是一个比较小的文件,大多数情况下<1MB)

更新-

多亏了 Laurent 的指针,我才得以使用以下方法:

var net = require('net'),
     fs = require('fs'),
     async = require('async');

var server = net.createServer(function (socket) {
  var lines = fs.readFileSync(__dirname + '/data-small.txt').toString().split(/\n+/);

  async.whilst(
    function () {
      return lines.length > 0;
    },
    function (done) {
        var line = lines.shift();
        socket.write(line + '\r\n');
        setTimeout(done, /^\$X,/.test(line) ? 1000 : 0);
      },
    function (err) {
      // no more lines present
      socket.end();
    });
});

server.listen(8000);
console.log('server running on 8000');

我现在收到了一大串行,直到 $X,停顿 1 秒,然后它继续!谢谢!

深入研究我的第二部分:有没有办法同步这个人造服务器的输出,以便所有客户端无论何时连接都能看到相同的输出?

4

1 回答 1

0

如果你想让所有客户端保持同步,你需要做一些完全不同的事情。这是一个起点。此外,似乎net模块会更合适。

var net = 要求('net'),
    fs = 要求('fs'),
    _ = 要求('下划线');

无功电流 = 0,
    套接字 = [];

// 块的脏解析器
var data = fs.readFileSync(__dirname + '/data.txt').toString(),
    blocs = _.chain(data.split(/\$X,/)).compact().map(function (bloc) {
      返回 '​​$X,' + 块;
    })。价值();

函数流块(){
  console.log('写入 bloc #' + current + ' to ' + sockets.length + 'sockets');
  _(sockets).each(function (socket) {
    socket.write(块[当前]);
  });

  当前 = (当前 + 1) % blocs.length;
  设置超时(流块,1000);
}

var server = net.createServer(function (socket) {
  console.log('传入连接');

  // 立即写入当前块
  socket.write(块[当前]);

  // 添加到套接字以便它接收未来的块
  sockets.push(socket);

  // 客户端离开时清理
  socket.on('end', function () {
    sockets = _(sockets).without(socket);
  });
}).listen(8000, function () {
  console.log('服务器监听 8000 端口');
});

流块();
于 2013-05-01T21:12:55.857 回答