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方法,你不需要显式地传递额外的参数。
但是请注意, ConnectAction
, ListenAction
和device
不应该是全局variables,它们是特定于实例的,并且最好也是构造函数的作用域; 否则他们可能会干扰其他TCP服务器。
有没有更好的方法来解决这个问题?
有一个不同的,虽然不一定是更好的方法:将devName
作为一个属性放在你的对象上。 connectAction
在你的服务器的上下文中被调用,所以你可以简单地在那里访问它 – 至less,如果你的TcpServer
将从net.Server
inheritance,那将是这种情况。 由于你有一个包装你的服务器,你可以做这样的事情:
// 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
来帮忙。