Skip to content

Instantly share code, notes, and snippets.

@wichert
Created November 21, 2017 10:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wichert/9ebede4c68c5648424435c9507bc1e03 to your computer and use it in GitHub Desktop.
Save wichert/9ebede4c68c5648424435c9507bc1e03 to your computer and use it in GitHub Desktop.
Ably connection setup
// @flow
import * as Ably from 'ably'
import type Channel from 'ably/common/lib/client/channel'
import type ConnectionStateChange from 'ably/common/lib/client/connectionstatechange'
// import type ErrorInfo from 'ably/common/lib/types/errorinfo'
import winston from 'winston'
import EventEmitter from 'events'
type AuthHeaders = {[string]: string}
export type AblyEvent = {
type: string,
payload: any,
}
class AblyConnection extends EventEmitter {
channel: string
ably: Ably.Realtime
ablyChannel: ?Channel
constructor(channel: string, authUrl: string, authHeaders: AuthHeaders = {}) {
super()
this.channel = channel
this.ably = new Ably.Realtime({
transports: ['web_socket'],
authUrl,
authHeaders,
})
}
start(): Promise<void> {
return new Promise((resolve, reject) => {
const check = (event: ConnectionStateChange) => {
if (event.current === 'disconnected') {
winston.warn('Ably connection attempt failed, will keep retrtying')
} else if (event.current === 'suspended') {
// We failed for 2 minutes - just abort
winston.error('Ably connection failed')
this.ably.close()
reject()
return
} else if (event.current === 'failed') {
winston.error(`Ably connection failed: ${event.reason.message}`)
reject()
} else if (event.current === 'connected') {
winston.info('Ably connection established')
resolve()
return
}
this.ably.connection.once(check)
}
this.ably.connection.once(check)
})
.then(() => {
return new Promise((resolve, reject) => {
this.ablyChannel = this.ably.channels.get(this.channel)
this.ablyChannel.subscribe(this.onMessage.bind(this))
// flow-disable-next-line
this.ablyChannel.attach((err) => {
if (err) {
winston.error('Ably channel attach failed')
reject()
} else {
winston.info('Ably channel attach succeeded')
resolve()
}
})
})
})
}
stop(): Promise<void> {
if (this.ably.connected.state === 'connecting'
|| this.ably.connected.state === 'connected'
|| this.ably.connected.state === 'disconnected'
|| this.ably.connected.state === 'suspended'
) {
if (this.ablyChannel) {
this.ablyChannel.unsunscribe()
}
this.ably.close()
}
return Promise.resolve()
}
onMessage(msg: any): void {
winston.verbose(`Received ably message ${msg.name}`)
const event: AblyEvent = {
type: msg.name,
payload: msg.data,
}
this.emit('message', event)
}
}
export default AblyConnection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment