@@ -24,14 +24,12 @@ import {
24
24
FrameHandler ,
25
25
Multiplexer ,
26
26
Outbound ,
27
- serializeFrame ,
28
- } from "rsocket-core" ;
29
- import { Duplex } from "stream" ;
30
-
31
- export class WebsocketDuplexConnection
32
- extends Deferred
33
- implements DuplexConnection , Outbound
34
- {
27
+ serializeFrame
28
+ } from 'rsocket-core' ;
29
+ import { Duplex } from 'stream' ;
30
+ import WebSocket from 'ws' ;
31
+
32
+ export class WebsocketDuplexConnection extends Deferred implements DuplexConnection , Outbound {
35
33
readonly multiplexerDemultiplexer : Multiplexer & Demultiplexer & FrameHandler ;
36
34
37
35
constructor (
@@ -40,18 +38,16 @@ export class WebsocketDuplexConnection
40
38
multiplexerDemultiplexerFactory : (
41
39
frame : Frame ,
42
40
outbound : Outbound & Closeable
43
- ) => Multiplexer & Demultiplexer & FrameHandler
41
+ ) => Multiplexer & Demultiplexer & FrameHandler ,
42
+ private rawSocket : WebSocket . WebSocket
44
43
) {
45
44
super ( ) ;
46
45
47
- websocketDuplex . on ( " close" , this . handleClosed ) ;
48
- websocketDuplex . on ( " error" , this . handleError ) ;
49
- websocketDuplex . on ( " data" , this . handleMessage ) ;
46
+ websocketDuplex . on ( ' close' , this . handleClosed ) ;
47
+ websocketDuplex . on ( ' error' , this . handleError ) ;
48
+ websocketDuplex . on ( ' data' , this . handleMessage ) ;
50
49
51
- this . multiplexerDemultiplexer = multiplexerDemultiplexerFactory (
52
- frame ,
53
- this
54
- ) ;
50
+ this . multiplexerDemultiplexer = multiplexerDemultiplexerFactory ( frame , this ) ;
55
51
}
56
52
57
53
get availability ( ) : number {
@@ -77,32 +73,40 @@ export class WebsocketDuplexConnection
77
73
return ;
78
74
}
79
75
80
- // if (__DEV__) {
81
- // if (this._options.debug) {
82
- // console.log(printFrame(frame));
83
- // }
84
- // }
85
- const buffer =
86
- /* this._options.lengthPrefixedFrames
87
- ? serializeFrameWithLength(frame, this._encoders)
88
- :*/ serializeFrame ( frame ) ;
89
- // if (!this._socket) {
90
- // throw new Error(
91
- // "RSocketWebSocketClient: Cannot send frame, not connected."
92
- // );
93
- // }
94
- this . websocketDuplex . write ( buffer ) ;
76
+ try {
77
+ // if (__DEV__) {
78
+ // if (this._options.debug) {
79
+ // console.log(printFrame(frame));
80
+ // }
81
+ // }
82
+ const buffer =
83
+ /* this._options.lengthPrefixedFrames
84
+ ? serializeFrameWithLength(frame, this._encoders)
85
+ :*/ serializeFrame ( frame ) ;
86
+ // if (!this._socket) {
87
+ // throw new Error(
88
+ // "RSocketWebSocketClient: Cannot send frame, not connected."
89
+ // );
90
+ // }
91
+
92
+ // Work around for this issue
93
+ // https://github.com/websockets/ws/issues/1515
94
+ if ( this . rawSocket . readyState == this . rawSocket . CLOSING || this . rawSocket . readyState == this . rawSocket . CLOSED ) {
95
+ this . close ( new Error ( 'WebSocket is closing' ) ) ;
96
+ return ;
97
+ }
98
+
99
+ this . websocketDuplex . write ( buffer ) ;
100
+ } catch ( ex ) {
101
+ this . close ( new Error ( ex . reason || `Could not write to WebSocket duplex connection: ${ ex } ` ) ) ;
102
+ }
95
103
}
96
104
97
- private handleClosed = ( e : CloseEvent ) : void => {
98
- this . close (
99
- new Error (
100
- e . reason || "WebsocketDuplexConnection: Socket closed unexpectedly."
101
- )
102
- ) ;
105
+ private handleClosed = ( e : WebSocket . CloseEvent ) : void => {
106
+ this . close ( new Error ( e . reason || 'WebsocketDuplexConnection: Socket closed unexpectedly.' ) ) ;
103
107
} ;
104
108
105
- private handleError = ( e : ErrorEvent ) : void => {
109
+ private handleError = ( e : WebSocket . ErrorEvent ) : void => {
106
110
this . close ( e . error ) ;
107
111
} ;
108
112
@@ -125,23 +129,27 @@ export class WebsocketDuplexConnection
125
129
126
130
static create (
127
131
socket : Duplex ,
128
- connectionAcceptor : (
129
- frame : Frame ,
130
- connection : DuplexConnection
131
- ) => Promise < void > ,
132
+ connectionAcceptor : ( frame : Frame , connection : DuplexConnection ) => Promise < void > ,
132
133
multiplexerDemultiplexerFactory : (
133
134
frame : Frame ,
134
135
outbound : Outbound & Closeable
135
- ) => Multiplexer & Demultiplexer & FrameHandler
136
+ ) => Multiplexer & Demultiplexer & FrameHandler ,
137
+ rawSocket : WebSocket . WebSocket
136
138
) : void {
137
139
// TODO: timeout on no data?
138
- socket . once ( "data" , async ( buffer ) => {
139
- const frame = deserializeFrame ( buffer ) ;
140
- const connection = new WebsocketDuplexConnection (
141
- socket ,
142
- frame ,
143
- multiplexerDemultiplexerFactory
144
- ) ;
140
+ socket . once ( 'data' , async ( buffer ) => {
141
+ let frame : Frame | undefined = undefined ;
142
+ try {
143
+ frame = deserializeFrame ( buffer ) ;
144
+ if ( ! frame ) {
145
+ throw new Error ( `Unable to deserialize frame` ) ;
146
+ }
147
+ } catch ( ex ) {
148
+ // The initial frame should always be parsable
149
+ return socket . end ( ) ;
150
+ }
151
+
152
+ const connection = new WebsocketDuplexConnection ( socket , frame , multiplexerDemultiplexerFactory , rawSocket ) ;
145
153
if ( connection . done ) {
146
154
return ;
147
155
}
0 commit comments