6 import { type RawData
, WebSocketServer
} from
'ws'
9 type ClusterWorkerData
,
10 type ClusterWorkerResponse
,
14 type ThreadWorkerData
,
15 type ThreadWorkerResponse
,
18 const emptyFunction
= (): void => {
22 class WebSocketServerWorker
extends ClusterWorker
<
26 private static wss
: WebSocketServer
27 private static requestHandlerPool
: DynamicThreadPool
<
28 ThreadWorkerData
<DataPayload
>,
29 ThreadWorkerResponse
<DataPayload
>
32 private static readonly startWebSocketServer
= (
33 workerData
?: ClusterWorkerData
34 ): ClusterWorkerResponse
=> {
35 const { port
, workerFile
, minWorkers
, maxWorkers
, ...poolOptions
} =
36 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39 WebSocketServerWorker
.requestHandlerPool
= new DynamicThreadPool
<
40 ThreadWorkerData
<DataPayload
>,
41 ThreadWorkerResponse
<DataPayload
>
44 maxWorkers
?? availableParallelism(),
49 WebSocketServerWorker
.wss
= new WebSocketServer({ port
}, () => {
51 `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port.toString()}/`
55 WebSocketServerWorker
.wss
.on('connection', ws
=> {
56 ws
.on('error', console
.error
)
57 ws
.on('message', (message
: RawData
) => {
58 const { type, data
} = JSON
.parse(
59 // eslint-disable-next-line @typescript-eslint/no-base-to-string
61 ) as MessagePayload
<DataPayload
>
63 case MessageType
.echo
:
64 WebSocketServerWorker
.requestHandlerPool
65 .execute({ data
}, 'echo')
69 type: MessageType
.echo
,
77 case MessageType
.factorial
:
78 WebSocketServerWorker
.requestHandlerPool
79 .execute({ data
}, 'factorial')
84 type: MessageType
.factorial
,
88 typeof v
=== 'bigint' ? v
.toString() : v
100 port
: WebSocketServerWorker
.wss
.options
.port
,
104 public constructor () {
105 super(WebSocketServerWorker
.startWebSocketServer
, {
106 killHandler
: async () => {
107 await WebSocketServerWorker
.requestHandlerPool
.destroy()
108 WebSocketServerWorker
.wss
.close()
114 export const webSocketServerWorker
= new WebSocketServerWorker()