2013-01-22 32 views
1

我的应用程序使用node.js时遇到问题。 我写了一个允许网页和PLC之间通信的小应用程序。 与网页的通信基于socket.io,与PLC的通信基于net.createConnection。Node.js:同一消息的多个副本

我的应用程序从Web页面接收的命令,则它创建一个标准的消息取/写入协议和发送的那些消息给PLC。 PLC响应也基于F/W协议,当从我的应用程序收到响应消息时,它应解码并仅向网页发送少量信息。

所有过程工作,但我看到(如果取或写并不重要)来自PLC的消息被复制一次每次操作后。 例如:

Fetch operation -> Response: Data 
Fetch operation -> Response: Data Data 
Fetch operation -> Response: Data Data Data 
... 

我使用Wireshark来检查,如果这是一个PLC问题,但该消息是正确的并且是唯一的一个。 我觉得有一个node.js缓冲区或类似的问题。

有什么建议吗?

下面的代码:

/*** 
    Fetch-Write protocol in Node.js 
    Massimo Milluzzo - [email protected] 
***/ 


// Packages needed 
var httpd = require('http').createServer(handler); 
var io = require('socket.io').listen(httpd); 
var fs = require('fs'); 
var net = require('net'); 

// Connection variables 
var host = "192.168.0.220";  // Ip of PLC 
var port = 2002;    // Port for the comunication with PLC 
httpd.listen(4000);    // Listening the browser on port 4000 
var conn = null;    // Manage the connection 
var message = null;    // Message 

// Manage HTML request 
function handler(req, res) { 
    fs.readFile(__dirname + '/index.html', 
     function(err, data) { 
      if (err) { 
       res.writeHead(500); 
       return res.end('Error loading index.html'); 
      } 
      res.writeHead(200); 
      res.end(data); 
     } 
    ); 
} 

// When is created the connection of the socket 
io.sockets.on('connection', function (socket) { 
    console.log('connected'); 

    // Test function 
    socket.on('message', function(content) { 
     console.log(content); 
     socket.emit('serverMessage', 'I\'m here'); 
    }); 

    // Need to write -> set the message 
    socket.on('write', function(content){ 
     // See fetch-write protocol documentation 
     message = new Uint8Array([83,53,16,1,3,3,3,8,0x01,content[0],0,content[1],0,content[2],255,2,0,content[3]]); 
     connect(content); 
    }); 

    socket.on('fetch', function(content) { 
     // See fetch-write protocol documentation 
     message = new Uint8Array([83,53,16,1,3,5,3,8,0x01,content[0],0,content[1],0,content[2],255,2]); 
     connect(content); 
    }); 

    // Main function for the communication with PLC 
    function connect(content){ 
     // Console writing 
     console.log(content); 
     socket.emit('serverMessage', 'Message received...try to comunicate with PLC'); 

     // If there isn't a connection create one 
     if(conn == null) 
      conn = net.createConnection(port,host); 


     // If gets an error print it 
     conn.on('error', function(err) { 
      console.log('Error in connection:', err); 
      socket.emit('error',""+err); 
     }); 

     // On connection close write it 
     conn.on('close', function() { 
      console.log('connection got closed'); 
      socket.emit('serverMessage','connection got closed'); 
     }); 

     // When data is received decode the message 
     conn.on('data', function(data) { 
      console.log('some data has arrived:', ""+data); 

      // See fetch-write protocol documentation 
      if((data[0] == 0x53) && 
       (data[1] == 0x35) && 
       (data[2] == 0x10) && 
       (data[3] == 0x01) && 
       (data[4] == 0x03) && 
       ((data[5] == 0x06) || (data[5] == 0x04)) && // 06: fetch | 04: write 
       (data[6] == 0x0F) && 
       (data[7] == 0x03) && 
       ((data[8] == 0x00) || (data[8] == 0x02) || (data[8] == 0x03) || (data[8] == 0x06)) && // Error code, see fetch-write protocol documentation 
       (data[9] == 0xFF) && 
       (data[10] == 0x07)) 
      { 
       switch(data[8]){ 
        // No error 
        case 0x00: 
         // Fetch 
         if(data[5] == 0x06){ 
          // Get the response of PLC 
          var i; 
          var mex = ""; 
          for(i = 16; i<data.length; i=i+2){ 
           mex = mex + "[" + data[i].toString(16) + " " + data[i+1].toString(16) + "]"; 
          } 
          // Write it 
          socket.emit('serverMessage','Value read: ' + mex); 
          mex = ""; 
         } 
         // Write 
         else if(data[5] == 0x06){ 
          socket.emit('serverMessage','PLC updated'); 
         } 
        break; 
        // Error 02: Requested block does not exist 
        case 0x02: 
         socket.emit('error','Requested block does not exist'); 
        break; 
        // Error 03: Requested block is to small 
        case 0x03: 
         socket.emit('error','Requested block is to small'); 
        break; 
        // Error 06: No valid ORG ID 
        case 0x06: 
         socket.emit('error','No valid ORG ID'); 
        break; 
        // Any other code, warning because not exist in the protocol 
        default: 
         var temp = ""+data[8]; 
         socket.emit('error','Unknown error ID ['+temp+']'); 
        break; 
       } 
      } 
      // The message doesn't correspond to the Fetch/Write protocol 
      else{ 
       socket.emit('error','Error while talking with PLC'); 
      } 
      data = ""; 
     }); 

     // Write the client message on the socket 
     conn.write(new Buffer(message,'ascii'), function() { 
      console.log('data was written out'); 
      socket.emit('serverMessage','data was written out'); 
     }); 
    } 
}); 

!更新!

我做了一些其他的测试,结果是不存在的邮件的实际排队,测试的结果是:

Data 
Data1 Data1 
Data  Data  Data 
Data2 Data2 Data2 Data2 
Data3 Data3 Data3 Data3 Data3 
Data1 Data1 Data1 Data1 Data1 Data1 

回答

0

解决

最后,我找到了解决办法,这是非常简单的:问题是,每当有一个操作,添加一个新“数据”监听器。

为了避免这种情况,我不得不将代码从改变:

conn.on('data', function(data) { 
    ... 
} 

到:

conn.once('data', function(data) { 
    ... 
} 
相关问题