rltm
Version:
abstraction for realtime frameworks
199 lines (127 loc) • 4.68 kB
JavaScript
"use strict";
// include NodeJS event emitter
const EventEmitter = require('events');
// include the Socket.io user library
const io = require('socket.io-client');
// represents a connection to a single channel
class Room extends EventEmitter {
constructor(endpoint, channel, uuid, state) {
// call the EventEmitter constructor
super();
// store this users uuid
this.uuid = uuid;
// assign the channel parameter as a property
this.channel = channel;
this.isReady = false;
// create a connection to the socketio endpoint
this.socket = io.connect(endpoint, {multiplex: true});
// subscribe to the socket.io connection event
this.socket.on('connect', () => {
// tell the server that we want to join a channel
this.socket.emit('channel', channel, this.uuid, state);
// tell the user the server is ready
this.onReady();
this.isReady = true;
});
// server says someone has joined
this.socket.on('join', (channel, uuid, state) => {
// make sure the channel is this channel
if(this.channel == channel) {
// emit the 'join' event to the user
this.emit('join', uuid, state);
}
});
// server says someone has left
this.socket.on('leave', (channel, uuid) => {
// make sure it's on this channel
if(this.channel == channel) {
// emit the 'leave' event to the user
this.emit('leave', uuid);
}
});
// server says someone has disconnected
this.socket.on('disconnect', (channel, uuid) => {
// make sure it's on this channel
if(this.channel == channel) {
// emit the 'leave' event to the user
this.emit('disconnect', uuid);
}
});
// a message is sent from the srever
this.socket.on('message', (channel, uuid, data) => {
// make sure it is on this channel
if(this.channel == channel) {
// tell the user of the new message
this.emit('message', uuid, data);
}
});
// a user sets their state
this.socket.on('state', (channel, uuid, state) => {
// make sure it is on this channel
if(this.channel == channel) {
// tell the user of the set state
this.emit('state', uuid, state);
}
});
}
ready(fn) {
this.onReady = fn;
if(this.isReady) {
this.onReady();
}
}
onReady() {
// waiting to be assigned by user
return;
}
message(data) {
return new Promise((resolve, reject) => {
// publish the data to the socket.io server
this.socket.emit('publish', this.channel, this.uuid, data, () =>{
resolve();
});
});
}
here() {
// ask socket.io-server for a list of online users
return new Promise((resolve, reject) => {
this.socket.emit('whosonline', this.channel, null, function(users) {
// callback with an object of users
resolve(users);
});
});
}
state(state) {
return new Promise((resolve, reject) => {
// tell socket.io-server to update this user's state
this.socket.emit('setState', this.channel, this.uuid, state, () => {
resolve();
});
});
}
history() {
return new Promise((resolve, reject) => {
// ask socket.io-server for the history of messages published
this.socket.emit('history', this.channel, (data) => {
// callback with an array of messages
resolve(data);
});
});
}
leave(channel) {
return new Promise((resolve, reject) => {
// manually disconnect from socket.io-server
this.socket.emit('leave', this.uuid, channel, () => {
resolve();
});
});
}
}
module.exports = function (setup) {
// convenience method to assign the service string name to itself
this.service = setup.service;
this.join = (channel, state) => {
return new Room(setup.config.endpoint, channel, setup.config.uuid, setup.config.state);
};
return this;
};