[英]JavaScript, node.js wait for socket.on response before continuing
[英]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方法,您无需显式传递额外的参数。
但是请注意, ConnectAction
, ListenAction
和device
不应是全局变量,它们是特定于实例的,并且最好将范围限定在构造函数中; 否则它们可能会干扰其他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.