import Util from '../../util';
import * as Collections from '../../utils/collections';
import Protocol from '../protocol/protocol';
import Connection from '../connection';
import TransportConnection from '../../transports/transport_connection';
import HandshakePayload from './handshake_payload';
/**
* Handles Pusher protocol handshakes for transports.
*
* Calls back with a result object after handshake is completed. Results
* always have two fields:
* - action - string describing action to be taken after the handshake
* - transport - the transport object passed to the constructor
*
* Different actions can set different additional properties on the result.
* In the case of 'connected' action, there will be a 'connection' property
* containing a Connection object for the transport. Other actions should
* carry an 'error' property.
*
* @param {AbstractTransport} transport
* @param {Function} callback
*/
export default class Handshake {
transport: TransportConnection;
callback: (HandshakePayload) => void;
onMessage: Function;
onClosed: Function;
constructor(
transport: TransportConnection,
callback: (HandshakePayload) => void
) {
this.transport = transport;
this.callback = callback;
this.bindListeners();
}
close() {
this.unbindListeners();
this.transport.close();
}
private bindListeners() {
this.onMessage = m => {
this.unbindListeners();
var result;
try {
result = Protocol.processHandshake(m);
} catch (e) {
this.finish('error', { error: e });
this.transport.close();
return;
}
if (result.action === 'connected') {
this.finish('connected', {
connection: new Connection(result.id, this.transport),
activityTimeout: result.activityTimeout
});
} else {
this.finish(result.action, { error: result.error });
this.transport.close();
}
};
this.onClosed = closeEvent => {
this.unbindListeners();
var action = Protocol.getCloseAction(closeEvent) || 'backoff';
var error = Protocol.getCloseError(closeEvent);
this.finish(action, { error: error });
};
this.transport.bind('message', this.onMessage);
this.transport.bind('closed', this.onClosed);
}
private unbindListeners() {
this.transport.unbind('message', this.onMessage);
this.transport.unbind('closed', this.onClosed);
}
private finish(action: string, params: any) {
this.callback(
Collections.extend({ transport: this.transport, action: action }, params)
);
}
}
|