单机集群,怎么才能给特定的设备发送一组数据呢?
发布于 9 年前 作者 CommanderXL 4614 次浏览 最后一次编辑是 8 年前 来自 问答

这两天给老师写一个web端→服务器端→硬件的项目。 现在就是在web端选定好操作数据后先发送到服务器端,然后服务器端发送给硬件,硬件设备是200多个传感器。

今天写程序的时候出现的一个问题就是:如果现在只有一个传感器,web端是能很好的和硬件通讯的,如果将硬件数量加到2个或者2个以上,如果我选择对A硬件进行发送数据,而另外的B,C不发送数据,就会出现一组数据会传给A硬件3遍。

我放部分代码,看大家能不能帮我分析下。

var express=require("express");
var app=express();
var cluster=require("cluster");
var TCP=require("net").createServer();  //创建tcp服务器
if(cluster.isMaster){
			var wk=cluster.fork();
			var http=require("http");
			var server=http.createServer(app);
			server.listen(8080);
			
			app.post("/",function(req,res){
					var data=req.body;		//获取从web端post过来的数据
					wk.send(data);		//将数据发送给worker
			})
}
else if(cluster.isWorker){
			var socketArr=[];
			TCP.on("connection",function(socket){
					socketArr.push(socket);
					process.on("message",function(data){
							socketArr[0].write("123");	
							//这里如果只有一个硬件相连,发送数据没问题,但是如果有A,B,C 3个硬件设备相连,那么A会收到3组“123”,而B,C 2个设备都不会受到数据。那么我应该怎么处理才能使A只能收到1组“123”呢?
					})
			})
}
17 回复

你的三个worker监听了同样的三个事件吧?所以你web发请求的时候才会每个worker都发了一次,只是从你上头的写法推敲的 自豪地采用 CNodeJS ionic

@luoyjx 那你的意思是不同的传感器tcp连接应该监听不同的事件咯?比如事件A,B,C分别是给A,B,C发数据,那么当有master传数据给worker的时候应该是这样的:

	process.on("message",function(data){
				//事件A发生
				//事件B,C不发生
	})

@CommanderXL 额,我想的不对 自豪地采用 CNodeJS ionic

每一个connection进来,你就监听一次message,当然有多少个连接就接收多少次啦

@CommanderXL 不清楚你发送的时候,设备和他对应的连接是怎么对应的,难道都是根据数组下标来取的么?

socketArr[0].write("123"); 

这是每次都发给第一个连接了?

@luoyjx 传感器是走的网线发送数据,IP地址是固定的,到时候根据IP来向不同的传感器发送数据。

奥,那个是我写的示例。

	//监听web端发送过来的数据。 我感觉楼上说的有道理。3个connection进来以后,监听一次message,所以有多少个链接就接收多少次了。
	process.on("message",function(){
			socketArr[0].write("123") ; //现在有3个TCP连接。每次web端来数据以后只向第一个TCP连接发送数据
	});		

@CommanderXL 你发送只会发送给某个worker,其他worker会触发message么?你每次发送的时候把pid打出来看看

@luoyjx

process.on("message",function(){
		console.log(data);			//这个data是从web端传过来的数据。
		console.log(“process.pid: ”+process.pid);	
		socketArr[0].write(data);		//A接受到了3组数据,B,C没有
})

QQ图片20150519124424.png

pid应该都是一样的,他们同属于一个进程。 其他的worker都会触发message. 那么我怎么才能让A只接受一条数据,B,C都不接受呢?

我发现我的回答赤裸裸的被忽略了,有点灰心,那就试下回复代码吧,虽然也不知道是否正确,但是好奇心告诉我,我好想知道结果。

var express=require("express");
var app=express();
var cluster=require("cluster");
var TCP=require("net").createServer();  //创建tcp服务器
if(cluster.isMaster){
            var wk=cluster.fork();
            var http=require("http");
            var server=http.createServer(app);
            server.listen(8080);
            
            app.post("/",function(req,res){
                    var data=req.body;      //获取从web端post过来的数据
                    wk.send(data);      //将数据发送给worker
            })
}
else if(cluster.isWorker){
            var socketArr=[];
            TCP.on("connection",function(socket){
                    socketArr.push(socket);
            })
			
                    process.on("message",function(data){
                            socketArr[0].write("123");  
                            //这里如果只有一个硬件相连,发送数据没问题,但是如果有A,B,C 3个硬件设备相连,那么A会收到3组“123”,而B,C 2个设备都不会受到数据。那么我应该怎么处理才能使A只能收到1组“123”呢?
                    })
}

@iamcc 额。确实是这样。。原来socketArr里面保存的socket对象是可以脱离TCP.on("connection",function(){.....})事件使用的。我一直以为如果脱离了链接事件,socketArr里面就不存在socket对象了。

谢谢~

@CommanderXL http请求只有一次么?感觉光说挺难解决问题的,从源头开始一点点调吧…

把 process.on(“message”… 往外移一级就行了。 目前的代码是每次 connection 发生,就会 attach 一个新的 message 监听器,有三个 connection 进来就有三个 listener , 所以一条 message 会有三个 onmessage listener 被执行。导致 stockArr[0] 会得到三个 123

@iamcc 嗯。确实你说的那样。~

@klesh 嗯。确实是你说的那样。

回到顶部