2017-11-16 4 views
1

리눅스 용 키보드 이벤트 파서를 쓰고 있는데, node.js을 사용하고 있습니다. 그것은 다소 괜찮아 보이지만 때때로 노드가 몇 바이트를 건너 뛰는 것처럼 보입니다. 나는 데이터를 얻기 위해 ReadStream을 사용하고있다. 처리하고, 구분자가있을 때 (내 경우에는 \n) 결국 출력한다.ReadStream에서 바이트를 건너 뛰고 있습니까?

// This method is called through this callback: 
// this.readStream = fs.createReadStream(this.path); 
// this.readStream.on("data", function(a) { self.parse_data(self, a); }); 

EventParser.prototype.parse_data = function(self, data) 
{ 
    /* 
    * Data format : 
    * { 
    * 0x00 : struct timeval time { long sec (8), long usec (8) }  (8 bytes) 
    * 0x08 : __u16 type             (2 bytes) 
    * 0x10 : __u16 code             (2 bytes) 
    * 0x12 : __s32 value            (4 bytes) 
    * }                 = (16 bytes) 
    */ 

    var dataBuffer = new Buffer(data); 
    var slicedBuffer = dataBuffer.slice(0, 16); 
    dataBuffer = dataBuffer.slice(16, dataBuffer.length); 

    while (dataBuffer.length > 0 && slicedBuffer.length == 16) 
    { 
    var type = GetDataType(slicedBuffer), 
     code = GetDataCode(slicedBuffer), 
     value = GetDataValue(slicedBuffer); 

    if (type == CST.EV.KEY) 
    { // Key was pressed: KEY event type 
     if (code == 42 && value == 1) { self.shift_pressed = true; } 
     if (code == 42 && value == 0) { self.shift_pressed = false; } 

     console.log(type + "\t" + code + "\t" + value + "\t(" + GetKey(self.shift_pressed, code) + ")") 
     // GetKey uses a static array to get the actual character 
     // based on whether the shift key is held or not 

     if (value == 1) 
     self.handle_processed_data(GetKey(self.shift_pressed, code)); 
     // handle_processed_data adds characters together, and outputs the string when encountering a 
     // separator character (in this case, '\n') 
    } 

    // Take a new slice, and loop. 
    slicedBuffer = dataBuffer.slice(0, 16); 
    dataBuffer = dataBuffer.slice(16, dataBuffer.length); 
    } 
} 

// My system is in little endian! 
function GetDataType(dataBuffer) { return dataBuffer.readUInt16LE(8); } 
function GetDataCode(dataBuffer) { return dataBuffer.readUInt16LE(10); } 
function GetDataValue(dataBuffer) { return dataBuffer.readInt32LE(12); } 

나는 기본적으로 데이터 구조가 Buffer를 사용하여 상단에 설명 채우고 해요 : 여기

은 읽기 데이터를 처리하는 내 클래스의 일부이다. 흥미로운 부분은 끝 부분에있는 console.log이며 콜백에 전달되는 모든 흥미로운 내용 ( KEY 이벤트와 관련 있음)이 인쇄됩니다. 다음과 같은 로그의 결과가 예상 결과에 완료하고, 실제 결과 :

EventParserConstructor: Listening to /dev/input/event19 
/* Expected result: CODE-128 */ 
/* Note that value 42 is the SHIFT key */ 
1 42 1 () 
1 46 1 (C) 
1 42 0 () 
1 46 0 (c) 
1 42 1 () 
1 24 1 (O) 
1 42 0 () 
1 24 0 (o) 
1 42 1 () 
1 32 1 (D) 
1 42 0 () 
1 32 0 (d) 
1 42 1 () 
1 18 1 (E) 
1 42 0 () 
1 18 0 (e) 
1 12 0 (-) 
1 2 0 (1) 
1 3 1 (2) 
1 3 0 (2) 
1 9 1 (8) 
1 9 0 (8) 
1 28 1 (
) 
[EventParser_Handler]/event_parser.handle_processed_data: CODE28 
/* Actual result: CODE28 */ 
/* The '-' and '1' events can be seen in the logs, but only */ 
/* as key RELEASED (value: 0), not key PRESSED */ 

우리는 -1 문자 이벤트가 있지만 중요한 자료로 지나가는 명확하게 볼 수 있습니다 (값 : 0) 키 누르기가 아닙니다. 가장 이상한 일은 대부분의 경우 이벤트가 올바르게 번역 된 것입니다. 그러나 시간의 10 %는 이런 일이 발생합니다.

ReadStream은 가끔씩 약간의 바이트를 먹고 있습니까? 그렇다면 어떤 대안을 사용해야합니까?

미리 감사드립니다.

답변

0

음, 내 루프가 썩은 것으로 나타났습니다.

데이터가 16 바이트의 청크로만 전송된다고 가정하고있었습니다 ... 분명히 항상 그런 것은 아닙니다. 가끔씩, <의 패킷이 16 바이트 남았고 두 개의 'data' 이벤트 콜백 사이에 손실되었습니다.

나는 데이터를 수신 할 때 excessBuffer 필드를 입력하고 그것을 사용하여 내 초기 slicedBuffer을 채 웁니다.

관련 문제