2013-06-26 35 views
5

Tôi đã tìm kiếm xung quanh và không tìm được câu hỏi chính xác mà tôi đang cố trả lời hoặc tôi cần ai đó giải thích cho tôi như tôi 'm 5.Thư viện mạng Node.js: nhận dữ liệu hoàn chỉnh từ sự kiện 'dữ liệu'

Về cơ bản, tôi có tập lệnh Node.js bằng cách sử dụng thư viện Net. Tôi đang kết nối với nhiều máy chủ và gửi lệnh cũng như nghe dữ liệu trả về.

var net = require('net'); 

var nodes = [ 
    'HOST1,192.168.179.8', 
    'HOST2,192.168.179.9', 
    'HOST3,192.168.179.10', 
    'HOST4,192.168.179.11' 
]; 

function connectToServer(tid, ip) { 
    var conn = net.createConnection(23, ip); 
    conn.on('connect', function() { 
     conn.write (login_string); // login string hidden in pretend variable 
    }); 
    conn.on('data', function(data) { 
     var read = data.toString(); 
     if (read.match(/Login Successful/)) { 
      console.log ("Connected to " + ip); 
      conn.write(command_string); 
     } 

     else if (read.match(/Command OK/)) { // command_string returned successful, 
                // read until /\r\nEND\r\n/ 

        // First part of data comes in here 
      console.log("Got a response from " + ip + ':' + read); 
     } 
     else { 
       //rest of data comes in here 
      console.log("Atonomous message from " + ip + ':' + read); 
     } 
    }); 
    conn.on('end', function() { 
     console.log("Lost conncection to " + ip + "!!"); 
    }); 
    conn.on('error', function(err) { 
     console.log("Connection error: " + err + " for ip " + ip); 
    }); 
} 

nodes.forEach(function(node) { 
    var nodeinfo = node.split(","); 
    connectToServer(nodeinfo[0], nodeinfo[1]); 
}); 

Dữ liệu kết thúc được chia thành hai phần. Ngay cả khi tôi lưu trữ dữ liệu trong một băm và chắp thêm phần đầu tiên vào phần còn lại khi tôi đọc/\ r \ nEND \ r \ n/dấu phân cách, có một đoạn bị mất ở giữa. Làm cách nào để đệm đúng dữ liệu để đảm bảo tôi nhận được thông báo đầy đủ từ luồng?

EDIT: Ok, điều này dường như được làm việc tốt hơn:

function connectToServer(tid, ip) { 
     var conn = net.createConnection(23, ip); 

     var completeData = ''; 

     conn.on('connect', function() { 
       conn.write (login_string); 
     }); 
     conn.on('data', function(data) { 
       var read = data.toString(); 

       if (read.match(/Login Successful/)) { 
         console.log ("Connected to " + ip); 

         conn.write(command_string); 
       } 
       else { 
         completeData += read; 
       } 

       if (completeData.match(/Command OK/)) { 
         if (completeData.match(/\r\nEND\r\n/)) { 
           console.log("Response: " + completeData); 
         } 
       } 
     }); 
     conn.on('end', function() { 
       console.log("Connection closed to " + ip); 
     }); 
     conn.on('error', function(err) { 
       console.log("Connection error: " + err + " for ip " + ip); 
     }); 
} 

vấn đề lớn nhất của tôi có lẽ là một lỗi logic. Tôi đã hoặc đang đợi đoạn tin bắt đầu trả lời, hoặc đoạn tin đã kết thúc nó. Tôi đã không cứu mọi thứ ở giữa.

Tôi đoán nếu tôi muốn nhận được tất cả Node-ish về nó, tôi nên kích hoạt một sự kiện bất cứ khi nào một thông điệp đầy đủ đến (bắt đầu bằng một dòng trống, kết thúc bằng 'END' trên một dòng của chính nó), và làm việc xử lý ở đó.

+0

Làm cách nào bạn phát hiện thấy một đoạn bị thiếu? Từ các thông báo gỡ lỗi đăng nhập vào giao diện điều khiển? –

+0

so sánh song song với thực hiện thủ công. –

Trả lời

1

Vấn đề của tôi là vấn đề logic. Tôi đang tìm kiếm đoạn tin nhắn bắt đầu tin nhắn, hoặc đoạn tin nhắn đã kết thúc thông điệp, và bỏ qua mọi thứ ở giữa. Tôi đoán dự kiến ​​toàn bộ câu trả lời sẽ đến trong một hoặc hai đoạn.

Đây là mã làm việc, được dán từ phía trên. Có lẽ có nhiều cách làm Node-ish hơn (tôi thực sự sẽ phát ra một sự kiện cho từng đoạn thông tin), nhưng tôi sẽ đánh dấu nó là câu trả lời trừ khi có ai đó đăng một phiên bản tốt hơn vào thời điểm này ngày mai.

function connectToServer(tid, ip) { 
     var conn = net.createConnection(23, ip); 

     var completeData = ''; 

     conn.on('connect', function() { 
       conn.write (login_string); 
     }); 
     conn.on('data', function(data) { 
       var read = data.toString(); 

       if (read.match(/Login Successful/)) { 
         console.log ("Connected to " + ip); 

         conn.write(command_string); 
       } 
       else { 
         completeData += read; 
       } 

       if (completeData.match(/Command OK/)) { 
         if (completeData.match(/\r\nEND\r\n/)) { 
           console.log("Response: " + completeData); 
         } 
       } 
     }); 
     conn.on('end', function() { 
       console.log("Connection closed to " + ip); 
     }); 
     conn.on('error', function(err) { 
       console.log("Connection error: " + err + " for ip " + ip); 
     }); 
} 
3

Bạn không nên làm bất cứ điều gì với dữ liệu bạn nhận được, cho đến khi bạn nhận được sự kiện kết thúc. Lệnh gọi kết thúc có nghĩa là tất cả các khối dữ liệu đã được gửi qua luồng tới các cuộc gọi lại của bạn. Nếu dữ liệu đến nhiều hơn một đoạn, bạn cần phải tạo một biến trong phần đóng của hàm để lưu trữ dữ liệu này. Hầu hết các chương trình có thể làm việc tốt chỉ bỏ qua thực tế này, bởi vì dữ liệu thường đi qua trong một đoạn. Nhưng đôi khi nó không. Nó thậm chí không nhất thiết phụ thuộc vào lượng dữ liệu. Nếu bạn đang ở trong một tình huống mà điều này đang xảy ra, tôi đã tạo ra một ví dụ trình diễn cách xử lý nó. Tôi về cơ bản đã sử dụng mã của bạn, nhưng loại bỏ tất cả các fluff ... đây chỉ là demoing logic bạn cần phải thu thập tất cả các dữ liệu và làm việc trên đó.

function connectToServer(tid, ip) { 
    var conn = net.createConnection(23, ip); 
    var completeData = ''; 

    conn.on('connect', function() { 
     conn.write (login_string); // login string hidden in pretend variable 
    }); 
    conn.on('data', function(data) { 
     completeData += data; 
     var dataArray = completeData.split('your delimiter'); 
     if(dataArray.size > 1) { //If our data was split into several pieces, we have a complete chunk saved in the 0th position in the array 
      doWorkOnTheFirstHalfOfData(dataArray[0]); 
      completeData = dataArray[1];// The second portion of data may yet be incomplete, thise may need to be more complete logic if you can get more than one delimeter at a time... 
     } 
    }); 
    conn.on('end', function() { 
     //do stuff with the "completeData" variable in here. 
    }); 
} 
+0

+1 Mặc dù nó có vẻ như đó là những gì anh ta đang làm với băm, mã này với một biến cục bộ đơn giản là một cách đơn giản hơn nhiều (và dễ dàng hơn để gỡ lỗi) để làm điều tương tự. –

+0

@JoachimIsaksson - Tôi đồng ý rằng cách tiếp cận biến duy nhất tốt hơn nhiều, tôi chỉ gặp sự cố khi hiểu phạm vi của biến đó bằng cách thực hiện điều này trên nhiều thiết bị. –

+0

Tôi đoán tôi không hiểu sự kiện 'kết thúc'. Khi tôi chỉnh sửa mã của tôi trông giống như mã ở trên, tôi dường như không bao giờ có được sự kiện 'kết thúc'. Tôi sẽ nhận được rằng nếu tôi vẫn còn kết nối? –

Các vấn đề liên quan