Skip to content

Commit b77268b

Browse files
committed
Add support for connection.recv_timeout_seconds in the Browser Channel
The implementation of the timeout connection hint has changed. The control of when start and stop the timeout has moved to the `channel-channel` instead of relying on the socket timeout configuration. This change enables the `browser-channel` to implement the `receive timeout` which was not possible before since the `WebSocket` doesn't have a timeout configuration.
1 parent c6164d7 commit b77268b

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

packages/bolt-connection/src/channel/browser/browser-channel.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ export default class WebSocketChannel {
5353
this._error = null
5454
this._handleConnectionError = this._handleConnectionError.bind(this)
5555
this._config = config
56+
this._receiveTimeout = null
57+
this._receiveTimeoutStarted = false
58+
this._receiveTimeoutId = null
5659

5760
const { scheme, error } = determineWebSocketScheme(config, protocolSupplier)
5861
if (error) {
@@ -84,6 +87,7 @@ export default class WebSocketChannel {
8487
}
8588
}
8689
this._ws.onmessage = event => {
90+
this._resetTimeout()
8791
if (self.onmessage) {
8892
const b = new ChannelBuffer(event.data)
8993
self.onmessage(b)
@@ -111,7 +115,7 @@ export default class WebSocketChannel {
111115
}
112116

113117
// onerror triggers on websocket close as well.. don't get me started.
114-
if (this._open) {
118+
if (this._open && !this._timedout) {
115119
// http://stackoverflow.com/questions/25779831/how-to-catch-websocket-connection-to-ws-xxxnn-failed-connection-closed-be
116120
this._error = newError(
117121
'WebSocket connection failure. Due to security ' +
@@ -181,18 +185,56 @@ export default class WebSocketChannel {
181185
* @param {number} receiveTimeout The amount of time the channel will keep without receive any data before timeout (ms)
182186
* @returns {void}
183187
*/
184-
setupReceiveTimeout (receiveTimeout) {}
188+
setupReceiveTimeout (receiveTimeout) {
189+
this._receiveTimeout = receiveTimeout
190+
}
185191

186192
/**
187193
* Stops the receive timeout for the channel.
188194
*/
189195
stopReceiveTimeout () {
196+
if (this._receiveTimeout !== null && this._receiveTimeoutStarted) {
197+
this._receiveTimeoutStarted = false
198+
if (this._receiveTimeoutId != null) {
199+
clearTimeout(this._receiveTimeoutId)
200+
}
201+
this._receiveTimeoutId = null
202+
}
190203
}
191204

192205
/**
193206
* Start the receive timeout for the channel.
194207
*/
195208
startReceiveTimeout () {
209+
if (this._receiveTimeout !== null && !this._receiveTimeoutStarted) {
210+
this._receiveTimeoutStarted = true
211+
this._resetTimeout()
212+
}
213+
}
214+
215+
_resetTimeout () {
216+
if (!this._receiveTimeoutStarted) {
217+
return
218+
}
219+
220+
if (this._receiveTimeoutId !== null) {
221+
clearTimeout(this._receiveTimeoutId)
222+
}
223+
224+
this._receiveTimeoutId = setTimeout(() => {
225+
this._receiveTimeoutId = null
226+
this._timedout = true
227+
this.stopReceiveTimeout()
228+
this._error = newError(
229+
`Connection lost. Server didn't respond in ${this._receiveTimeout}ms`,
230+
this._config.connectionErrorCode
231+
)
232+
233+
this.close()
234+
if (this.onerror) {
235+
this.onerror(this._error)
236+
}
237+
}, this._receiveTimeout)
196238
}
197239

198240
/**

0 commit comments

Comments
 (0)