繁体   English   中英

Node.js JavaScript如何在TCP服务器中以“ socket.on”的方式访问异步事件处理程序中的对象数据?

[英]Node.js JavaScript how to access oject data in asynchronous event handlers as “socket.on” in TCP servers?

我试图在事件处理程序中找到访问现有对象的正确策略,并想知道我在此处提出的绕过方案是否是一个不错的选择。

在下面的示例中,我有一个用于构建简单TCPServer的类 在服务器创建之后,当新的tcpclient到达时,在“ ConnectAction”函数中,我需要访问“ devName”变量以查找所关注的服务器实例。 因此,“ DevName”不能是全局的,需要特定于我的TCPServer对象的当前实例。

  ------ Extract from my code --------
  // TCPserver Object Class
  TcpServer = function (devName, port) {

  // event handler executed each time a new TCP client connect to the server
  ConnectAction = function (socket) {      
      // for ech new client we create a new device and store it within server object
      device = new TCPClient (devName, socket);
  };

  this.server = net.createServer(ConnectAction);
  this.server.listen(port);
  return this;
  }
  Server1 = new TcpServer ("My First Server", 8080):
  Server2 = new TcpServer ("My Second Server", 8081):

在我过去使用的其他脚本语言中,可以向事件处理程序添加一个额外的参数。 但是在NODE.JS中,类似server = net.createServer(ConnectAction SomeExtraHandler); 不起作用。

我发现的唯一绕过的方法是利用在对象构造时传递的参数。 如本例所示,将事件处理程序代码嵌入对象边界内时; 然后,即使处理程序在TCPserver对象上下文之外被称为“此未定义” ,处理程序仍可以利用在对象创建时传递的参数。 在这种情况下为“ devName”。

我的问题:我的旁路安全吗? 有没有更好的方法来解决此问题? 我的示例的完整代码可在以下位置获得: http : //www.fridu.org/download/private/TcpServer.js

如果有人有更好的策略,我会很乐意了解它。 在我的实际应用程序中,我应该有十个左右的差异服务器实例,每个实例都有数百个客户端连接。 哪个提出了第二个问题,我在node.js中的对象编码方法是否支持负载?

我的问题:我的旁路安全吗?

是的,这是完全安全的。 使用闭包是解决此问题的JavaScript方法,您无需显式传递额外的参数。

但是请注意, ConnectActionListenActiondevice不应是全局变量,它们是特定于实例的,并且最好将范围限定在构造函数中; 否则它们可能会干扰其他tcp服务器。

有没有更好的方法来解决此问题?

有一种不同的方法,尽管不一定更好,它是:将devName作为属性放在对象上。 在您的服务器上下文中调用connectAction ,因此您可以在那里简单地访问它-至少如果TcpServer将从net.Server继承则是这种情况。 当服务器周围有包装器时,您可以执行以下操作:

// event handler executed each time a new TCP client connect to the server
function ConnectAction(socket) {      
    // for ech new client we create a new device and store it within tcp server object
    this.tcp.device = new TCPClient (this.tco.devName, socket);
}
function TcpServer(devName, port) {
    this.devName = devName;
    this.server = net.createServer(ConnectAction);
    this.server.tcp = this;
    this.server.listen(port);
}

像已经在使用devName一样应该很好。 但是,如果出于某种原因想要或需要将ConnectAction函数移出TcpServer实现之外,则可以使用bind()完成您要尝试执行的操作。

相关文档:

当绑定函数被调用时,bind()还接受主要的默认参数来提供给目标函数。

在您的情况下,这意味着您可以创建已将devName设置为其参数之一的ConnectAction绑定版本。 它看起来像这样:

ConnectAction = function (devName, socket) {      
    // for ech new client we create a new device and store it within server object
    device = new TCPClient (devName, socket);
};

var boundConnectAction = ConnectAction.bind(undefined, devName)
this.server = net.createServer(boundConnectAction);

在该代码, boundConnectAction仍然会从名为createServer为正常( boundConnectAction(socket) ),但是,因为它势必ConnectAction与默认参数devName ,它会把这一呼吁,如果它是ConnectAction(devName, socket)

注意: bind()的第一个参数在绑定函数中用作this参数。 由于ConnectAction看起来不像是对象/类实例方法,因此我只是传递了undefined ,但是您可能希望根据用例传递其他信息。


至于关于节点处理负载的其他问题,我建议将十个左右的服务器实例拆分为单独的节点进程,以便更好地分配负载。 看一下child_process或可能的cluster来帮助解决这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM