initial addition of custom channels and clients
This commit is contained in:
parent
60562c3139
commit
df864790f9
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "braid",
|
||||
"version": "1.2",
|
||||
"version": "1.2.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -1,7 +1,9 @@
|
||||
import ChannelBase from './channels/channelBase';
|
||||
import ClientBase from './clients/clientBase';
|
||||
import PrivateClient from './clients/types/privateClient';
|
||||
import PublicChannel from './channels/types/publicChannel';
|
||||
import PrivateChannel from './channels/types/privateChannel';
|
||||
import CustomChannel from './channels/types/customChannel';
|
||||
import PublicClient from './clients/types/publicClient';
|
||||
import PrivateClient from './clients/types/privateClient';
|
||||
import CustomClient from './clients/types/customClient';
|
||||
|
||||
var logger = require('./logger');
|
||||
|
||||
@ -10,13 +12,13 @@ class ChannelManager {
|
||||
|
||||
constructor() {
|
||||
// create default channel...
|
||||
var channel: ChannelBase = new ChannelBase('default');
|
||||
var channel: PublicChannel = new PublicChannel('default');
|
||||
this.channels.push(channel);
|
||||
}
|
||||
|
||||
createChannel(data: any) {
|
||||
var channelExists: ChannelBase|PrivateChannel|null = this.channelExists(data.channel);
|
||||
var channel: ChannelBase|PrivateChannel;
|
||||
var channelExists: PublicChannel|PrivateChannel|CustomChannel|null = this.channelExists(data.channel);
|
||||
var channel: PublicChannel|PrivateChannel|CustomChannel;
|
||||
|
||||
if (channelExists) {
|
||||
channel = channelExists;
|
||||
@ -40,8 +42,8 @@ class ChannelManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
addClientToChannel(client: ClientBase|PrivateClient, channel_id: string) {
|
||||
var channel: ChannelBase|PrivateChannel|null = this.channelExists(channel_id);
|
||||
addClientToChannel(client: PublicClient|PrivateClient|CustomClient, channel_id: string) {
|
||||
var channel: PrivateChannel|PrivateChannel|CustomChannel|null = this.channelExists(channel_id);
|
||||
|
||||
if (channel) {
|
||||
channel.addClient(client);
|
||||
@ -63,7 +65,7 @@ class ChannelManager {
|
||||
} catch (e) {
|
||||
logger.errorLog.info(e);
|
||||
logger.accessLog.info(`creating base channel: ${data.channel}`);
|
||||
return new ChannelBase(data.channel);
|
||||
return new PublicChannel(data.channel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +85,7 @@ class ChannelManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
changeChannel(client: ClientBase|PrivateClient, changeRequest: any) {
|
||||
changeChannel(client: PublicClient|PrivateClient|CustomClient, changeRequest: any) {
|
||||
if (client.channel != null) {
|
||||
this.removeClientFromChannel(client.id, client.channel.id)
|
||||
}
|
||||
|
@ -1,21 +1,44 @@
|
||||
import ClientBase from '../clients/clientBase';
|
||||
import PublicClient from '../clients/types/publicClient';
|
||||
import PrivateClient from '../clients/types/privateClient';
|
||||
import CustomClient from '../clients/types/customClient';
|
||||
import * as Joi from 'joi';
|
||||
|
||||
var logger = require('../logger');
|
||||
|
||||
class ChannelBase {
|
||||
id: string;
|
||||
clients: PrivateClient[]|ClientBase[] = [];
|
||||
clients: PrivateClient[]|PublicClient[]|CustomClient[] = [];
|
||||
|
||||
constructor(id: string) {
|
||||
this.id = id;
|
||||
logger.accessLog.info('Channel Created', {channelId: id});
|
||||
}
|
||||
|
||||
addClient(client: PrivateClient|ClientBase) {
|
||||
validations() {
|
||||
return {}
|
||||
}
|
||||
|
||||
broadcastMessage(from: PublicClient|PrivateClient|CustomClient, message: object) {
|
||||
for (let to of this.clients) {
|
||||
if (this.messageTransactionPossible(from, to)) {
|
||||
to.ws.send(JSON.stringify(message));
|
||||
logger.accessLog.info(`sent to ${to.id}`, { data: { message: message }});
|
||||
} else {
|
||||
logger.accessLog.info(`client is unable to send: ${to.id}`, { data: { message: message }});
|
||||
}
|
||||
}
|
||||
|
||||
return {'status': 'success', 'message': `message broadcast complete`};
|
||||
}
|
||||
|
||||
messageTransactionPossible(_from: PublicClient|PrivateClient|CustomClient, _to: PublicClient|PrivateClient|CustomClient) {
|
||||
return true
|
||||
}
|
||||
|
||||
addClient(client: PublicClient|PrivateClient|CustomClient) {
|
||||
if (this.clientExists(client.id)) {
|
||||
logger.errorLog.info('Client already exits in channel', {channelId: this.id, clientId: client.id});
|
||||
return {'status': 'notice', 'message': 'client aleady exists in channel'};
|
||||
return {'status': 'notice', 'message': 'client already exists in channel'};
|
||||
} else {
|
||||
this.clients.push(client);
|
||||
logger.accessLog.info('Added client to channel', {channelId: this.id, clientId: client.id});
|
||||
@ -44,19 +67,6 @@ class ChannelBase {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
broadcastMessage(from: ClientBase|null, message: string) {
|
||||
for (let client of this.clients) {
|
||||
if (client != from) {
|
||||
client.ws.send(JSON.stringify(message));
|
||||
logger.accessLog.info(`sent to ${client.id}`, { data: { message: message }});
|
||||
} else {
|
||||
logger.accessLog.info(`client is same as sender: ${client.id}`, { data: { message: message }});
|
||||
}
|
||||
}
|
||||
|
||||
return {'status': 'success', 'message': `message broadcast complete`};
|
||||
}
|
||||
};
|
||||
|
||||
export default ChannelBase;
|
||||
|
@ -0,0 +1,18 @@
|
||||
import CustomClient from '../../clients/types/customClient';
|
||||
import ChannelBase from '../channelBase';
|
||||
import * as Joi from 'joi';
|
||||
|
||||
class CustomChannel extends ChannelBase {
|
||||
validations() {
|
||||
return {
|
||||
test: Joi.alternatives().try(Joi.string(), Joi.object())
|
||||
}
|
||||
}
|
||||
|
||||
messageTransactionPossible(from: CustomClient, to: CustomClient) {
|
||||
return true
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = CustomChannel;
|
||||
export default CustomChannel;
|
@ -4,18 +4,12 @@ import ChannelBase from '../channelBase';
|
||||
var logger = require('../../logger');
|
||||
|
||||
class PrivateChannel extends ChannelBase {
|
||||
broadcastMessage(from: PrivateClient, message: any) {
|
||||
for (let client of this.clients) {
|
||||
if (client != from && client.roles.includes('receiver') && from.roles.includes('broadcaster')) {
|
||||
console.log('sending message: ' + JSON.stringify(message))
|
||||
client.ws.send(JSON.stringify(message));
|
||||
logger.accessLog.info(`sent to ${client.id}`, { data: { message: message }});
|
||||
} else {
|
||||
logger.accessLog.info(`client is either just a broadcaster or is the sender: ${client.id}`, { data: { message: message }});
|
||||
}
|
||||
}
|
||||
|
||||
return {'status': 'success', 'message': `message broadcast complete`};
|
||||
messageTransactionPossible(from: PrivateClient, to: PrivateClient) {
|
||||
return (
|
||||
to != from &&
|
||||
to.roles.includes('receiver') &&
|
||||
from.roles.includes('broadcaster')
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
import PublicClient from '../../clients/types/publicClient';
|
||||
import ChannelBase from '../channelBase';
|
||||
|
||||
var logger = require('../../logger');
|
||||
|
||||
class PublicChannel extends ChannelBase {
|
||||
messageTransactionPossible(from: PublicClient, to: PublicClient) {
|
||||
return (
|
||||
to != from
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = PublicChannel;
|
||||
export default PublicChannel;
|
@ -1,12 +1,13 @@
|
||||
import * as WebSocket from 'ws';
|
||||
import ClientBase from './clients/clientBase';
|
||||
import PublicClient from './clients/types/publicClient';
|
||||
import PrivateClient from './clients/types/privateClient';
|
||||
import CustomClient from './clients/types/customClient';
|
||||
import ChannelManager from './channelManager';
|
||||
|
||||
var logger = require('./logger');
|
||||
|
||||
class ClientManager {
|
||||
clients: ClientBase[]|PrivateClient[] = [];
|
||||
clients: PublicClient[]|PrivateClient[]|CustomClient[] = [];
|
||||
|
||||
constructor() {
|
||||
//...maybe one day
|
||||
@ -26,7 +27,7 @@ class ClientManager {
|
||||
}
|
||||
|
||||
clientsOfType(client_type: string) {
|
||||
var result: ClientBase[]|PrivateClient[] = [];
|
||||
var result: PublicClient[]|PrivateClient[]|CustomClient[] = [];
|
||||
|
||||
for (let client of this.clients) {
|
||||
if (client.type() == client_type) {
|
||||
@ -76,7 +77,7 @@ class ClientManager {
|
||||
} catch (e) {
|
||||
logger.errorLog.info(e);
|
||||
logger.accessLog.info(`creating base client: ${data.user_id}`);
|
||||
return new ClientBase(data, ws, channelManager, this);
|
||||
return new PublicClient(data, ws, channelManager, this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,8 +1,9 @@
|
||||
import * as WebSocket from 'ws';
|
||||
import ClientManager from '../clientManager';
|
||||
import ChannelManager from '../channelManager';
|
||||
import ChannelBase from '../channels/channelBase';
|
||||
import Private from '../channels/types/privateChannel';
|
||||
import PublicChannel from '../channels/types/publicChannel';
|
||||
import PrivateChannel from '../channels/types/privateChannel';
|
||||
import CustomChannel from '../channels/types/customChannel';
|
||||
|
||||
var messageManager = require('../messageManager');
|
||||
var logger = require('../logger');
|
||||
@ -11,7 +12,7 @@ class ClientBase {
|
||||
ws: WebSocket;
|
||||
data: any;
|
||||
id: number;
|
||||
channel: ChannelBase|Private|null;
|
||||
channel: PublicChannel|PrivateChannel|CustomChannel|null;
|
||||
clientManager: ClientManager;
|
||||
channelManager: ChannelManager;
|
||||
roles: Array<string>;
|
||||
@ -26,6 +27,10 @@ class ClientBase {
|
||||
this.roles = ['receiver']
|
||||
}
|
||||
|
||||
validations() {
|
||||
return {}
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.data;
|
||||
}
|
||||
@ -38,12 +43,12 @@ class ClientBase {
|
||||
return this.data.client;
|
||||
}
|
||||
|
||||
connectToChannel(channel: Private) {
|
||||
connectToChannel(channel: PublicChannel|PrivateChannel|CustomChannel) {
|
||||
this.channel = channel;
|
||||
|
||||
var messageListener = (message: any) => {
|
||||
logger.accessLog.info(`starting message transaction on channel ${channel.id}: `, {message: message});
|
||||
message = messageManager.prepareMessage(message);
|
||||
message = messageManager.prepareMessage(message, channel, this);
|
||||
|
||||
if (!message.error) {
|
||||
if (message['message_type'] == 'broadcast') {
|
||||
|
@ -0,0 +1,17 @@
|
||||
import ClientBase from '../clientBase';
|
||||
import * as Joi from 'joi';
|
||||
|
||||
class CustomClient extends ClientBase {
|
||||
// validations() {
|
||||
// return {
|
||||
// test: Joi.alternatives().try(Joi.string(), Joi.object())
|
||||
// }
|
||||
// }
|
||||
validations() {
|
||||
return { what: "test"}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = CustomClient;
|
||||
export default CustomClient;
|
||||
|
@ -6,7 +6,6 @@ import ChannelManager from '../../channelManager';
|
||||
var logger = require('../../logger');
|
||||
|
||||
class PrivateClient extends ClientBase {
|
||||
|
||||
constructor(data: any, ws: WebSocket, channelManager: ChannelManager, clientManager: ClientManager) {
|
||||
super(data, ws, channelManager, clientManager);
|
||||
this.roles = data.user_roles
|
||||
|
@ -0,0 +1,9 @@
|
||||
import ClientBase from '../clientBase';
|
||||
|
||||
var logger = require('../../logger');
|
||||
|
||||
class PublicClient extends ClientBase {};
|
||||
|
||||
module.exports = PublicClient;
|
||||
export default PublicClient;
|
||||
|
@ -1,21 +1,31 @@
|
||||
import * as Joi from 'joi';
|
||||
import PublicChannel from './channels/types/publicChannel';
|
||||
import PrivateChannel from './channels/types/privateChannel';
|
||||
import CustomChannel from './channels/types/customChannel';
|
||||
import PublicClient from './clients/types/publicClient';
|
||||
import PrivateClient from './clients/types/privateClient';
|
||||
import CustomClient from './clients/types/customClient';
|
||||
|
||||
var logger = require('./logger');
|
||||
var app = require('./config/app');
|
||||
|
||||
let schema = {
|
||||
message_type: Joi.string().valid(app.messageTypes).insensitive().required(),
|
||||
channel: Joi.string(),
|
||||
channel_type: Joi.string(),
|
||||
client_type: Joi.string(),
|
||||
user_id: Joi.number().integer(),
|
||||
message: Joi.alternatives().try(Joi.string(), Joi.object()),
|
||||
let schema = (channel: PublicChannel|PrivateChannel|CustomChannel, client: PublicClient|PrivateClient|CustomClient) => {
|
||||
let validations = {
|
||||
message_type: Joi.string().valid(app.messageTypes).insensitive().required(),
|
||||
channel: Joi.string(),
|
||||
channel_type: Joi.string(),
|
||||
client_type: Joi.string(),
|
||||
user_id: Joi.number().integer(),
|
||||
message: Joi.alternatives().try(Joi.string(), Joi.object())
|
||||
}
|
||||
|
||||
return {...validations, ...channel.validations, ...client.validations}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
prepareMessage: (message: string) => {
|
||||
prepareMessage: (message: string, channel: PublicChannel|PrivateChannel|CustomChannel, client: PublicClient|PrivateClient|CustomClient) => {
|
||||
var parsed = JSON.parse(message)
|
||||
const result = Joi.validate(parsed, schema);
|
||||
const result = Joi.validate(parsed, schema(channel, client));
|
||||
|
||||
if (result.error) {
|
||||
return result
|
||||
|
@ -14,7 +14,7 @@ var wsClient = new WebSocketClient();
|
||||
var channel: ChannelBase;
|
||||
var clientManager = new ClientManager();
|
||||
var channelManager = new ChannelManager();
|
||||
var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name }
|
||||
var data: any = { 'channel_type': 'private', 'client_type':'private', 'user_id': 125, 'user_roles': ['broadcaster', 'receiver'], 'channel': name }
|
||||
var client: ClientBase = new ClientBase(data, wsClient, channelManager, clientManager);
|
||||
|
||||
describe('ChannelBase', function () {
|
||||
|
@ -8,7 +8,7 @@ var assert = require('chai').assert;
|
||||
var sinon = require('sinon');
|
||||
|
||||
var name: string = 'test channel';
|
||||
var data: any = { 'client': 'test', 'client_type':'site', 'user_id': 125, 'user_type': 'user', 'channel': name }
|
||||
var data: any = { 'channel_type': 'private', 'client_type':'private', 'user_id': 125, 'user_roles': ['broadcaster', 'receiver'], 'channel': name }
|
||||
var WebSocketClient = require('websocket').client;
|
||||
var wsClient = new WebSocketClient();
|
||||
var clientManager = new ClientManager();
|
||||
@ -23,7 +23,7 @@ describe('ClientManager', function () {
|
||||
});
|
||||
|
||||
it('should get clients of type', function () {
|
||||
var result = clientManager.clientsOfType('site');
|
||||
var result = clientManager.clientsOfType('private');
|
||||
assert(result.length > 0, 'returns one client');
|
||||
});
|
||||
|
||||
@ -52,7 +52,7 @@ describe('ClientManager', function () {
|
||||
});
|
||||
|
||||
it('should add client of type PrivateClient', function () {
|
||||
var data: any = { 'channel_type': 'private', 'client_type':'private', 'user_id': 125, 'user_roles': '["broadcaster", "receiver"]', 'channel': name }
|
||||
var data: any = { 'channel_type': 'private', 'client_type': 'private', 'user_id': 125, 'user_roles': ['broadcaster', 'receiver'], 'channel': name }
|
||||
var result = clientManager.getClientType(data, channelManager, wsClient);
|
||||
expect(result.clientType()).to.be.equal('private');
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user