Created
November 21, 2017 10:39
-
-
Save wichert/9ebede4c68c5648424435c9507bc1e03 to your computer and use it in GitHub Desktop.
Ably connection setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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