Node.js JavaScript如何在TCP服务器中将asynchronous事件处理程序中的oject数据作为“socket.on”访问?

我试图find正确的策略,从我的事件处理程序中访问现有的对象,并怀疑我在这里提出的绕过是否是一个好的select。

在下面的示例中,我有一个类来构build一个简单的TCPServer 。 在服务器创build时间之后,当新的tcpclient到达时,在“ConnectAction”函数中,我需要访问“devName”variables来查找哪个服务器实例。 因此,“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的东西像服务器= net.createServer(ConnectAction SomeExtraHandler); 不起作用。

我发现的唯一的绕过是利用在对象构build时传递的参数。 当事件处理程序代码被embedded在对象边框内时,如本例所示; 那么即使处理程序在TCPserver对象上下文“this not defined”之外被调用,处理程序仍然可以利用在创build对象时传递的参数。 在这种情况下“devName”。

我的问题:我的旁路是否安全? 有没有更好的方法来解决这个问题? 我的示例的完整代码可在以下urlfind: http : //www.fridu.org/download/private/TcpServer.js

如果有人有更好的策略,我会很乐意去了解它。 在我的真实应用程序中,我应该有十个左右的服务器实例,每个客户端连接几百个客户端。 这引发了第二个问题,node.js中的对象编码方法是否支持加载?

我的问题:我的旁路是否安全?

是的,这是完全安全的。 使用闭包是解决这个问题的JavaScript方法,你不需要显式地传递额外的参数。

但是请注意, ConnectActionListenActiondevice不应该是全局variables,它们是特定于实例的,并且最好也是构造函数的作用域; 否则他们可能会干扰其他TCP服务器。

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

有一个不同的,虽然不一定是更好的方法:将devName作为一个属性放在你的对象上。 connectAction在你的服务器的上下文中被调用,所以你可以简单地在那里访问它 – 至less,如果你的TcpServer将从net.Serverinheritance,那将是这种情况。 由于你有一个包装你的服务器,你可以做这样的事情:

 // 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()也接受引用的默认参数,以便在调用绑定函数时提供给目标函数。

这意味着你的情况是你可以创build一个绑定版本的ConnectAction ,它已经将devName设置为其参数之一。 它看起来像这样:

 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仍然会被正常的调用( boundConnectAction(socket) ),但是,因为它被绑定到了一个默认参数devName ConnectAction ,所以它会像调用ConnectAction(devName, socket)一样传递这个调用。

注意:在绑定函数中, bind()的第一个参数被用作this参数。 由于ConnectAction看起来不像是一个对象/类实例方法,我只是通过了undefined ,但是你可能想传递一些其他的东西,这取决于你的用例。


至于你关于节点处理负载的其他问题,我build议将10个左右的服务器实例拆分成单独的节点进程,以便更好地分配负载。 看看child_process或者可能是cluster来帮忙。