node.js を使用するアプリケーションに問題があります。Web ページと PLC 間の通信を可能にする小さなアプリケーションを作成しました。Web ページとの通信は socket.io に基づいており、PLC との通信は net.createConnection に基づいています。
私のアプリケーションは Web ページからコマンドを受け取り、標準のフェッチ/書き込みプロトコルでメッセージを作成し、それらのメッセージを PLC に送信します。PLC の応答も F/W プロトコルに基づいています。アプリケーションから応答メッセージを受信すると、デコードして Web ページに送信する情報はごくわずかです。
すべてのプロセスが機能していますが、すべての操作 (フェッチまたは書き込みの場合は重要ではありません) の後、PLC からのメッセージがもう一度複製されることがわかります。例えば:
Fetch operation -> Response: Data
Fetch operation -> Response: Data Data
Fetch operation -> Response: Data Data Data
...
これが PLC の問題であるかどうかを確認するために、wireshark を使用しましたが、メッセージは正しく、1 つだけです。node.js バッファなどに問題があると思います。
なにか提案を?
コードは次のとおりです。
/***
Fetch-Write protocol in Node.js
Massimo Milluzzo - massimo.milluzzo@gmail.com
***/
// 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
等々