@@ -8,13 +8,14 @@ import * as http from 'http';
8
8
import { Payload , RSocketServer } from 'rsocket-core' ;
9
9
import * as ws from 'ws' ;
10
10
import { SocketRouterObserver } from './SocketRouterListener.js' ;
11
+ import { WebsocketDuplexConnection } from './transport/WebsocketDuplexConnection.js' ;
11
12
import { WebsocketServerTransport } from './transport/WebSocketServerTransport.js' ;
12
13
import {
13
14
CommonParams ,
14
15
IReactiveStream ,
15
16
IReactiveStreamInput ,
16
- RS_ENDPOINT_TYPE ,
17
17
ReactiveSocketRouterOptions ,
18
+ RS_ENDPOINT_TYPE ,
18
19
SocketResponder
19
20
} from './types.js' ;
20
21
@@ -24,6 +25,7 @@ export interface ReactiveStreamRequest {
24
25
dataMimeType : string ;
25
26
initialN : number ;
26
27
responder : SocketResponder ;
28
+ connection : WebsocketDuplexConnection ;
27
29
}
28
30
29
31
export interface SocketBaseContext {
@@ -51,7 +53,30 @@ export class ReactiveSocketRouter<C extends SocketBaseContext> {
51
53
* This follows a similar pattern to the Journey Micro
52
54
* web sockets router.
53
55
*/
54
- const wss = new ws . WebSocketServer ( { noServer : true } ) ;
56
+ const wss = new ws . WebSocketServer ( {
57
+ noServer : true ,
58
+ perMessageDeflate : {
59
+ zlibDeflateOptions : {
60
+ chunkSize : 128 * 1024 , // default is 16kb - increased for better efficiency
61
+ memLevel : 7 , // default is 8
62
+ level : 3
63
+ } ,
64
+ zlibInflateOptions : {
65
+ // for decompressing messages from the client
66
+ chunkSize : 32 * 1024
67
+ } ,
68
+ // don't keep client context between messages
69
+ clientNoContextTakeover : true ,
70
+ // keep context between messages from the server
71
+ serverNoContextTakeover : false ,
72
+ // bigger window uses more memory and potentially more cpu. 10-15 is a good range.
73
+ serverMaxWindowBits : 12 ,
74
+ // Limit concurrent compression threads
75
+ concurrencyLimit : 8 ,
76
+ // Size (in bytes) below which messages should not be compressed _if context takeover is disabled_.
77
+ threshold : 1024
78
+ }
79
+ } ) ;
55
80
server . on ( 'upgrade' , ( request , socket , head ) => {
56
81
wss . handleUpgrade ( request , socket as any , head , ( ws ) => {
57
82
wss . emit ( 'connection' , ws , request ) ;
@@ -66,7 +91,9 @@ export class ReactiveSocketRouter<C extends SocketBaseContext> {
66
91
const rSocketServer = new RSocketServer ( {
67
92
transport,
68
93
acceptor : {
69
- accept : async ( payload ) => {
94
+ accept : async ( payload , rsocket ) => {
95
+ const connection = ( rsocket as any ) . connection as WebsocketDuplexConnection ;
96
+
70
97
const { max_concurrent_connections } = this . options ?? { } ;
71
98
logger . info ( `Currently have ${ wss . clients . size } active WebSocket connection(s)` ) ;
72
99
// wss.clients.size includes this connection, so we check for greater than
@@ -104,7 +131,7 @@ export class ReactiveSocketRouter<C extends SocketBaseContext> {
104
131
// TODO: Consider limiting the number of active streams per connection to prevent abuse
105
132
handleReactiveStream (
106
133
context ,
107
- { payload, initialN, responder, dataMimeType, metadataMimeType } ,
134
+ { payload, initialN, responder, dataMimeType, metadataMimeType, connection } ,
108
135
observer ,
109
136
abortController ,
110
137
params
@@ -191,6 +218,7 @@ export async function handleReactiveStream<Context extends SocketBaseContext>(
191
218
context,
192
219
observer,
193
220
signal : abortController . signal ,
221
+ connection : request . connection ,
194
222
responder
195
223
} ) ;
196
224
if ( ! isAuthorized . authorized ) {
@@ -207,6 +235,7 @@ export async function handleReactiveStream<Context extends SocketBaseContext>(
207
235
observer,
208
236
signal : abortController . signal ,
209
237
responder,
238
+ connection : request . connection ,
210
239
initialN
211
240
} ) ;
212
241
} catch ( ex ) {
0 commit comments