Files
Daniel Holmgren 1dd20d3a81 WebSocket Library (#4348)
* create new websocket lib

* switch out ozone impl

* keepalive test

* remove websocket keepalive code from xrpc-server

* add the package in all the spots

* websocket -> ws-client

* missed ref

* fix import in ozone test
2025-11-18 17:34:41 -06:00

51 lines
1.6 KiB
TypeScript

import getPort from 'get-port'
import { WebSocketServer } from 'ws'
import { wait } from '@atproto/common'
import { CloseCode, WebSocketKeepAlive } from '../src'
describe('WebSocketKeepAlive', () => {
it('uses a heartbeat to reconnect if a connection is dropped', async () => {
// we run a server that, on first connection, pauses for longer than the heartbeat interval (doesn't return "pong"s)
// on second connection, it sends a message and then closes
const port = await getPort()
const server = new WebSocketServer({ port })
let firstConnection = true
let firstWasClosed = false
server.on('connection', async (socket) => {
if (firstConnection === true) {
firstConnection = false
socket.pause()
await wait(600)
// shouldn't send this message because the socket would be closed
socket.send(Buffer.from('error message'), (err) => {
if (err) throw err
socket.close(CloseCode.Normal)
})
socket.on('close', () => {
firstWasClosed = true
})
} else {
socket.send(Buffer.from('test message'), (err) => {
if (err) throw err
socket.close(CloseCode.Normal)
})
}
})
const wsKeepAlive = new WebSocketKeepAlive({
getUrl: async () => `ws://localhost:${port}`,
heartbeatIntervalMs: 500,
})
const messages: Uint8Array[] = []
for await (const msg of wsKeepAlive) {
messages.push(msg)
}
expect(messages).toHaveLength(1)
expect(Buffer.from(messages[0]).toString()).toBe('test message')
expect(firstWasClosed).toBe(true)
server.close()
})
})