1
0
forked from mirror/misskey
mi.moris.day/src/web/app/common/scripts/streaming/stream.ts

97 lines
2.3 KiB
TypeScript
Raw Normal View History

declare const _API_URL_: string;
2017-11-17 01:24:44 +09:00
import { EventEmitter } from 'eventemitter3';
2017-11-10 01:11:46 +09:00
import * as ReconnectingWebsocket from 'reconnecting-websocket';
2017-03-18 20:05:11 +09:00
2017-05-11 05:08:12 +09:00
/**
2017-06-09 01:03:54 +09:00
* Misskey stream connection
2017-05-11 05:08:12 +09:00
*/
2017-11-17 01:24:44 +09:00
export default class Connection extends EventEmitter {
2017-11-13 18:05:35 +09:00
private state: string;
private buffer: any[];
private socket: ReconnectingWebsocket;
constructor(endpoint, params?) {
2017-11-17 01:24:44 +09:00
super();
//#region BIND
2017-03-18 20:05:11 +09:00
this.onOpen = this.onOpen.bind(this);
this.onClose = this.onClose.bind(this);
this.onMessage = this.onMessage.bind(this);
2017-03-20 14:49:24 +09:00
this.send = this.send.bind(this);
2017-03-18 20:05:11 +09:00
this.close = this.close.bind(this);
2017-11-17 01:24:44 +09:00
//#endregion
2017-03-20 14:49:24 +09:00
2017-03-18 20:05:11 +09:00
this.state = 'initializing';
2017-03-21 18:14:59 +09:00
this.buffer = [];
2017-03-18 20:05:11 +09:00
const host = _API_URL_.replace('http', 'ws');
2017-06-09 01:03:54 +09:00
const query = params
? Object.keys(params)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
.join('&')
: null;
2017-11-10 01:11:46 +09:00
this.socket = new ReconnectingWebsocket(`${host}/${endpoint}${query ? '?' + query : ''}`);
2017-03-18 20:05:11 +09:00
this.socket.addEventListener('open', this.onOpen);
this.socket.addEventListener('close', this.onClose);
this.socket.addEventListener('message', this.onMessage);
}
2017-05-11 05:08:12 +09:00
/**
* Callback of when open connection
*/
2017-11-13 18:05:35 +09:00
private onOpen() {
2017-03-18 20:05:11 +09:00
this.state = 'connected';
2017-11-17 01:24:44 +09:00
this.emit('_connected_');
2017-03-21 18:14:59 +09:00
// バッファーを処理
const _buffer = [].concat(this.buffer); // Shallow copy
this.buffer = []; // Clear buffer
_buffer.forEach(message => {
this.send(message); // Resend each buffered messages
});
2017-03-18 20:05:11 +09:00
}
2017-05-11 05:08:12 +09:00
/**
* Callback of when close connection
*/
2017-11-13 18:05:35 +09:00
private onClose() {
2017-03-18 20:05:11 +09:00
this.state = 'reconnecting';
2017-11-17 01:24:44 +09:00
this.emit('_closed_');
2017-03-18 20:05:11 +09:00
}
2017-05-11 05:08:12 +09:00
/**
* Callback of when received a message from connection
*/
2017-11-13 18:05:35 +09:00
private onMessage(message) {
2017-02-18 13:18:59 +09:00
try {
2017-02-19 08:02:59 +09:00
const msg = JSON.parse(message.data);
2017-11-17 01:24:44 +09:00
if (msg.type) this.emit(msg.type, msg.body);
2017-11-13 18:05:35 +09:00
} catch (e) {
2017-02-18 13:18:59 +09:00
// noop
}
2017-03-18 20:05:11 +09:00
}
2017-02-18 13:18:59 +09:00
2017-05-11 05:08:12 +09:00
/**
* Send a message to connection
*/
2017-11-13 18:05:35 +09:00
public send(message) {
2017-03-21 18:14:59 +09:00
// まだ接続が確立されていなかったらバッファリングして次に接続した時に送信する
if (this.state != 'connected') {
this.buffer.push(message);
return;
2017-11-13 18:05:35 +09:00
}
2017-03-21 18:14:59 +09:00
2017-03-20 13:54:59 +09:00
this.socket.send(JSON.stringify(message));
}
2017-05-11 05:08:12 +09:00
/**
* Close this connection
*/
2017-11-13 18:05:35 +09:00
public close() {
2017-03-18 20:05:11 +09:00
this.socket.removeEventListener('open', this.onOpen);
this.socket.removeEventListener('message', this.onMessage);
}
}