6 import { type RawData
, WebSocketServer
} from
'ws'
8 type ClusterWorkerData
,
9 type ClusterWorkerResponse
,
13 type ThreadWorkerData
,
14 type ThreadWorkerResponse
17 const emptyFunction
= (): void => {
21 class WebSocketServerWorker
extends ClusterWorker
<
25 private static wss
: WebSocketServer
26 private static requestHandlerPool
: DynamicThreadPool
<
27 ThreadWorkerData
<DataPayload
>,
28 ThreadWorkerResponse
<DataPayload
>
31 private static readonly startWebSocketServer
= (
32 workerData
?: ClusterWorkerData
33 ): ClusterWorkerResponse
=> {
34 const { port
, workerFile
, minWorkers
, maxWorkers
, ...poolOptions
} =
35 workerData
as ClusterWorkerData
37 WebSocketServerWorker
.requestHandlerPool
= new DynamicThreadPool
<
38 ThreadWorkerData
<DataPayload
>,
39 ThreadWorkerResponse
<DataPayload
>
42 maxWorkers
?? availableParallelism(),
47 WebSocketServerWorker
.wss
= new WebSocketServer({ port
}, () => {
49 `⚡️[ws server]: WebSocket server is started in cluster worker at ws://localhost:${port}/`
53 WebSocketServerWorker
.wss
.on('connection', ws
=> {
54 ws
.on('error', console
.error
)
55 ws
.on('message', (message
: RawData
) => {
56 const { type, data
} = JSON
.parse(
57 // eslint-disable-next-line @typescript-eslint/no-base-to-string
59 ) as MessagePayload
<DataPayload
>
61 case MessageType
.echo
:
62 WebSocketServerWorker
.requestHandlerPool
63 .execute({ data
}, 'echo')
67 type: MessageType
.echo
,
75 case MessageType
.factorial
:
76 WebSocketServerWorker
.requestHandlerPool
77 .execute({ data
}, 'factorial')
81 type: MessageType
.factorial
,
94 port
: WebSocketServerWorker
.wss
.options
.port
98 public constructor () {
99 super(WebSocketServerWorker
.startWebSocketServer
, {
100 killHandler
: async () => {
101 await WebSocketServerWorker
.requestHandlerPool
.destroy()
102 WebSocketServerWorker
.wss
.close()
108 export const webSocketServerWorker
= new WebSocketServerWorker()