Skip to content

Commit 36e5d36

Browse files
committed
Client.ts: use chained event listeners
1 parent 3320290 commit 36e5d36

File tree

1 file changed

+71
-75
lines changed

1 file changed

+71
-75
lines changed

src/Client.ts

Lines changed: 71 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import debug from "debug"
2-
import WebSocket, { ErrorEvent } from "isomorphic-ws"
2+
import { WebSocket } from "isomorphic-ws"
33
import pkg from "../package.json" assert { type: "json" }
44
import { EventEmitter } from "./lib/EventEmitter.js"
55
import { isReady } from "./lib/isReady.js"
@@ -118,86 +118,82 @@ export class Client extends EventEmitter<ClientEvents> {
118118
const url = `${this.url}/introduction/${this.userName}`
119119
this.log("connecting to relay server", url)
120120

121-
const serverConnection = new WebSocket(url)
122-
123-
serverConnection.onopen = async () => {
124-
await isReady(serverConnection)
125-
this.retryDelay = this.minRetryDelay
126-
this.shouldReconnectIfClosed = true
127-
this.drainQueue()
128-
this.emit("server.connect")
129-
this.open = true
130-
131-
this.heartbeat = setInterval(
132-
() => serverConnection.send(HEARTBEAT),
133-
HEARTBEAT_INTERVAL
134-
)
135-
}
136-
137-
serverConnection.onmessage = messageEvent => {
138-
const data = messageEvent.data as Uint8Array
139-
const message = unpack(data) as Message.ServerToClient
140-
141-
// The only kind of message that we receive from the relay server is an introduction, which tells
142-
// us that someone else is interested in the same thing we are.
143-
if (message.type !== "Introduction")
144-
throw new Error(`Invalid message type '${message.type}'`)
145-
146-
// When we receive that message, we respond by requesting a "direct" connection to the peer
147-
// (via piped sockets on the relay server) for each document ID that we have in common
148-
149-
const connectToPeer = (documentId: DocumentId, userName: UserName) => {
150-
const peer = this.get(userName)
151-
if (peer.has(documentId)) return // don't add twice
152-
peer.set(documentId, null)
153-
154-
const url = `${this.url}/connection/${this.userName}/${userName}/${documentId}`
155-
const peerConnection = new WebSocket(url)
156-
157-
peerConnection.onopen = async () => {
158-
// make sure the socket is actually in READY state
159-
await isReady(peerConnection)
160-
161-
// add the socket to the map for this peer
162-
peer.set(documentId, peerConnection)
163-
this.emit("peer.connect", {
164-
userName,
165-
documentId,
166-
socket: peerConnection,
167-
} as PeerEventPayload)
168-
}
169-
170-
// if the other end disconnects, we disconnect
171-
peerConnection.onclose = () => {
172-
this.closeSocket(userName, documentId)
173-
this.emit("peer.disconnect", {
174-
userName,
175-
documentId,
176-
socket: peerConnection,
177-
} as PeerEventPayload)
121+
this.serverConnection = new WebSocket(url)
122+
123+
.on("open", async () => {
124+
await isReady(this.serverConnection)
125+
this.retryDelay = this.minRetryDelay
126+
this.shouldReconnectIfClosed = true
127+
this.drainQueue()
128+
this.emit("server.connect")
129+
this.open = true
130+
131+
this.heartbeat = setInterval(
132+
() => this.serverConnection.send(HEARTBEAT),
133+
HEARTBEAT_INTERVAL
134+
)
135+
})
136+
137+
.on("message", data => {
138+
const message = unpack(data) as Message.ServerToClient
139+
140+
// The only kind of message that we receive from the relay server is an introduction, which tells
141+
// us that someone else is interested in the same thing we are.
142+
if (message.type !== "Introduction")
143+
throw new Error(`Invalid message type '${message.type}'`)
144+
145+
// When we receive that message, we respond by requesting a "direct" connection to the peer
146+
// (via piped sockets on the relay server) for each document ID that we have in common
147+
148+
const connectToPeer = (documentId: DocumentId, userName: UserName) => {
149+
const peer = this.get(userName)
150+
if (peer.has(documentId)) return // don't add twice
151+
peer.set(documentId, null)
152+
153+
const url = `${this.url}/connection/${this.userName}/${userName}/${documentId}`
154+
const peerConnection = new WebSocket(url)
155+
156+
peerConnection.on("open", async () => {
157+
// make sure the socket is actually in READY state
158+
await isReady(peerConnection)
159+
160+
// add the socket to the map for this peer
161+
peer.set(documentId, peerConnection)
162+
this.emit("peer.connect", {
163+
userName,
164+
documentId,
165+
socket: peerConnection,
166+
} as PeerEventPayload)
167+
})
168+
169+
// if the other end disconnects, we disconnect
170+
peerConnection.onclose = () => {
171+
this.closeSocket(userName, documentId)
172+
this.emit("peer.disconnect", {
173+
userName,
174+
documentId,
175+
socket: peerConnection,
176+
} as PeerEventPayload)
177+
}
178178
}
179-
}
180-
181-
const { userName, documentIds = [] } = message
182-
documentIds.forEach(documentId => connectToPeer(documentId, userName))
183-
}
184179

185-
serverConnection.onclose = () => {
186-
this.open = false
187-
this.emit("server.disconnect")
180+
const { userName, documentIds = [] } = message
181+
documentIds.forEach(documentId => connectToPeer(documentId, userName))
182+
})
188183

189-
// stop heartbeat
190-
clearInterval(this.heartbeat)
184+
.on("close", () => {
185+
this.open = false
186+
this.emit("server.disconnect")
191187

192-
if (this.shouldReconnectIfClosed) this.tryToReopen()
193-
}
188+
// stop heartbeat
189+
clearInterval(this.heartbeat)
194190

195-
serverConnection.onerror = ({ error }) => {
196-
this.emit("error", error)
197-
}
191+
if (this.shouldReconnectIfClosed) this.tryToReopen()
192+
})
198193

199-
this.serverConnection = serverConnection
200-
return this.serverConnection
194+
.on("error", error => {
195+
this.emit("error", error)
196+
})
201197
}
202198

203199
/** Try to reconnect after a delay */

0 commit comments

Comments
 (0)