@@ -20,14 +20,23 @@ export class DbgpConnection extends EventEmitter {
20
20
private _chunks : Buffer [ ] ;
21
21
private _dataLength : number ;
22
22
private _parser : DOMParser ;
23
+ private _messages : Buffer [ ] = [ ] ;
24
+ private _processingMessages = false ;
23
25
24
26
public constructor ( socket : WebSocket ) {
25
27
super ( ) ;
26
28
this . _socket = socket ;
27
29
this . _parsingState = ParsingState . DataLength ;
28
30
this . _chunksDataLength = 0 ;
29
31
this . _chunks = [ ] ;
30
- socket . on ( "message" , ( data : string ) : void => this . _handleDataChunk ( Buffer . from ( data ) ) ) ;
32
+ socket . on ( "message" , ( data : string ) : void => {
33
+ this . _messages . push ( Buffer . from ( data ) ) ;
34
+ if ( ! this . _processingMessages ) {
35
+ this . _processingMessages = true ;
36
+ this . _handleDataChunk ( ) ;
37
+ this . _processingMessages = false ;
38
+ }
39
+ } ) ;
31
40
socket . on ( "error" , ( error : Error ) : boolean => this . emit ( "error" , error ) ) ;
32
41
socket . on ( "close" , ( ) : boolean => this . emit ( "close" ) ) ;
33
42
this . _parser = new DOMParser ( {
@@ -61,7 +70,9 @@ export class DbgpConnection extends EventEmitter {
61
70
} ) ;
62
71
}
63
72
64
- private _handleDataChunk ( data : Buffer ) {
73
+ private _handleDataChunk ( ) {
74
+ if ( ! this . _messages . length ) return ; // Shouldn't ever happen
75
+ const data : Buffer = this . _messages . shift ( ) ;
65
76
if ( this . _parsingState === ParsingState . DataLength ) {
66
77
// does data contain a NULL byte?
67
78
const separatorIndex = data . indexOf ( "|" ) ;
@@ -80,11 +91,13 @@ export class DbgpConnection extends EventEmitter {
80
91
if ( data . length > separatorIndex + 1 ) {
81
92
// handle the rest of the packet as part of the response
82
93
const rest = data . slice ( separatorIndex + 1 , this . _dataLength + separatorIndex + 1 ) ;
83
- this . _handleDataChunk ( rest ) ;
94
+ this . _messages . unshift ( rest ) ;
95
+ this . _handleDataChunk ( ) ;
84
96
// more then one data chunk in one message
85
97
const restData = data . slice ( this . _dataLength + separatorIndex + 1 ) ;
86
98
if ( restData . length ) {
87
- this . _handleDataChunk ( restData ) ;
99
+ this . _messages . unshift ( restData ) ;
100
+ this . _handleDataChunk ( ) ;
88
101
}
89
102
}
90
103
} else {
@@ -99,7 +112,7 @@ export class DbgpConnection extends EventEmitter {
99
112
// append the last piece of the response
100
113
const lastResponsePiece = data . slice ( 0 , this . _dataLength - this . _chunksDataLength ) ;
101
114
this . _chunks . push ( lastResponsePiece ) ;
102
- this . _chunksDataLength += data . length ;
115
+ this . _chunksDataLength += lastResponsePiece . length ;
103
116
const response = Buffer . concat ( this . _chunks , this . _chunksDataLength ) . toString ( "ascii" ) ;
104
117
// call response handler
105
118
const xml = iconv . decode ( Buffer . from ( response , "base64" ) , ENCODING ) ;
@@ -110,17 +123,19 @@ export class DbgpConnection extends EventEmitter {
110
123
this . _chunksDataLength = 0 ;
111
124
// switch to data length parsing state
112
125
this . _parsingState = ParsingState . DataLength ;
113
- // if data contains more info (except the NULL byte)
114
- if ( data . length > lastResponsePiece . length + 1 ) {
115
- // handle the rest of the packet (after the NULL byte) as data length
116
- const rest = data . slice ( lastResponsePiece . length + 1 ) ;
117
- this . _handleDataChunk ( rest ) ;
126
+ // if data contains more info
127
+ if ( data . length > lastResponsePiece . length ) {
128
+ // handle the rest of the packet as data length
129
+ const rest = data . slice ( lastResponsePiece . length ) ;
130
+ this . _messages . unshift ( rest ) ;
131
+ this . _handleDataChunk ( ) ;
118
132
}
119
133
} else {
120
134
// NO -> this is not the whole response yet. We buffer it and wait for the next data event.
121
135
this . _chunks . push ( data ) ;
122
136
this . _chunksDataLength += data . length ;
123
137
}
124
138
}
139
+ while ( this . _messages . length ) this . _handleDataChunk ( ) ;
125
140
}
126
141
}
0 commit comments