aboutsummaryrefslogtreecommitdiff
path: root/src/server/websocket.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/websocket.ts')
-rw-r--r--src/server/websocket.ts194
1 files changed, 100 insertions, 94 deletions
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 1b7f5919f..9b91a35a6 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -1,24 +1,24 @@
-import * as express from "express";
-import { blue, green } from "colors";
-import { createServer, Server } from "https";
-import { networkInterfaces } from "os";
+import { blue } from 'colors';
+import * as express from 'express';
+import { createServer, Server } from 'https';
+import { networkInterfaces } from 'os';
import * as sio from 'socket.io';
-import { Socket } from "socket.io";
-import { Utils } from "../Utils";
+import { Socket } from 'socket.io';
+import { Opt } from '../fields/Doc';
+import { Utils } from '../Utils';
import { logPort } from './ActionUtilities';
-import { timeMap } from "./ApiManagers/UserManager";
-import { GoogleCredentialsLoader, SSL } from "./apis/google/CredentialsLoader";
-import YoutubeApi from "./apis/youtube/youtubeApiSample";
-import { Client } from "./Client";
-import { Database } from "./database";
-import { DocumentsCollection } from "./IDatabase";
-import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from "./Message";
-import { Search } from "./Search";
+import { timeMap } from './ApiManagers/UserManager';
+import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader';
+import YoutubeApi from './apis/youtube/youtubeApiSample';
+import { initializeGuest } from './authentication/DashUserModel';
+import { Client } from './Client';
+import { Database } from './database';
+import { DocumentsCollection } from './IDatabase';
+import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from './Message';
+import { Search } from './Search';
import { resolvedPorts } from './server_Initialization';
-import { Opt } from "../fields/Doc";
export namespace WebSocket {
-
export let _socket: Socket;
const clients: { [key: string]: Client } = {};
export const socketMap = new Map<SocketIO.Socket, string>();
@@ -32,14 +32,14 @@ export namespace WebSocket {
resolvedPorts.socket = Number(socketPort);
}
let socketEndpoint: Opt<Server>;
- await new Promise<void>(resolve => socketEndpoint = createServer(SSL.Credentials, app).listen(resolvedPorts.socket, resolve));
+ await new Promise<void>(resolve => (socketEndpoint = createServer(SSL.Credentials, app).listen(resolvedPorts.socket, resolve)));
io = sio(socketEndpoint!, SSL.Credentials as any);
} else {
io = sio().listen(resolvedPorts.socket);
}
- logPort("websocket", resolvedPorts.socket);
+ logPort('websocket', resolvedPorts.socket);
- io.on("connection", function (socket: Socket) {
+ io.on('connection', function (socket: Socket) {
_socket = socket;
socket.use((_packet, next) => {
const userEmail = socketMap.get(socket);
@@ -70,14 +70,14 @@ export namespace WebSocket {
socket.join(room);
console.log('Client ID ' + socket.id + ' created room ' + room);
socket.emit('created', room, socket.id);
-
} else if (numClients === 1) {
console.log('Client ID ' + socket.id + ' joined room ' + room);
socket.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room, socket.id);
socket.in(room).emit('ready');
- } else { // max two clients
+ } else {
+ // max two clients
socket.emit('full', room);
}
});
@@ -97,10 +97,10 @@ export namespace WebSocket {
console.log('received bye');
});
- Utils.Emit(socket, MessageStore.Foo, "handshooken");
+ Utils.Emit(socket, MessageStore.Foo, 'handshooken');
Utils.AddServerHandler(socket, MessageStore.Bar, guid => barReceived(socket, guid));
- Utils.AddServerHandler(socket, MessageStore.SetField, (args) => setField(socket, args));
+ Utils.AddServerHandler(socket, MessageStore.SetField, args => setField(socket, args));
Utils.AddServerHandlerCallback(socket, MessageStore.GetField, getField);
Utils.AddServerHandlerCallback(socket, MessageStore.GetFields, getFields);
if (isRelease) {
@@ -126,26 +126,26 @@ export namespace WebSocket {
*/
disconnect = () => {
- socket.broadcast.emit("connection_terminated", Date.now());
+ socket.broadcast.emit('connection_terminated', Date.now());
socket.disconnect(true);
};
});
}
function processGesturePoints(socket: Socket, content: GestureContent) {
- socket.broadcast.emit("receiveGesturePoints", content);
+ socket.broadcast.emit('receiveGesturePoints', content);
}
function processOverlayTrigger(socket: Socket, content: MobileInkOverlayContent) {
- socket.broadcast.emit("receiveOverlayTrigger", content);
+ socket.broadcast.emit('receiveOverlayTrigger', content);
}
function processUpdateOverlayPosition(socket: Socket, content: UpdateMobileInkOverlayPositionContent) {
- socket.broadcast.emit("receiveUpdateOverlayPosition", content);
+ socket.broadcast.emit('receiveUpdateOverlayPosition', content);
}
function processMobileDocumentUpload(socket: Socket, content: MobileDocumentUploadContent) {
- socket.broadcast.emit("receiveMobileDocumentUpload", content);
+ socket.broadcast.emit('receiveMobileDocumentUpload', content);
}
function HandleYoutubeQuery([query, callback]: [YoutubeQueryInput, (result?: any[]) => void]) {
@@ -165,27 +165,22 @@ export namespace WebSocket {
const target: string[] = [];
onlyFields && target.push(DocumentsCollection);
await Database.Instance.dropSchema(...target);
- if (process.env.DISABLE_SEARCH !== "true") {
+ if (process.env.DISABLE_SEARCH !== 'true') {
await Search.clear();
}
+ initializeGuest();
}
function barReceived(socket: SocketIO.Socket, userEmail: string) {
clients[userEmail] = new Client(userEmail.toString());
const currentdate = new Date();
- const datetime = currentdate.getDate() + "/"
- + (currentdate.getMonth() + 1) + "/"
- + currentdate.getFullYear() + " @ "
- + currentdate.getHours() + ":"
- + currentdate.getMinutes() + ":"
- + currentdate.getSeconds();
+ const datetime = currentdate.getDate() + '/' + (currentdate.getMonth() + 1) + '/' + currentdate.getFullYear() + ' @ ' + currentdate.getHours() + ':' + currentdate.getMinutes() + ':' + currentdate.getSeconds();
console.log(blue(`user ${userEmail} has connected to the web socket at: ${datetime}`));
- socketMap.set(socket, userEmail + " at " + datetime);
+ socketMap.set(socket, userEmail + ' at ' + datetime);
}
function getField([id, callback]: [string, (result?: Transferable) => void]) {
- Database.Instance.getDocument(id, (result?: Transferable) =>
- callback(result ? result : undefined));
+ Database.Instance.getDocument(id, (result?: Transferable) => callback(result ? result : undefined));
}
function getFields([ids, callback]: [string[], (result: Transferable[]) => void]) {
@@ -193,9 +188,9 @@ export namespace WebSocket {
}
function setField(socket: Socket, newValue: Transferable) {
- Database.Instance.update(newValue.id, newValue, () =>
- socket.broadcast.emit(MessageStore.SetField.Message, newValue)); // broadcast set value to all other clients
- if (newValue.type === Types.Text) { // if the newValue has sring type, then it's suitable for searching -- pass it to SOLR
+ Database.Instance.update(newValue.id, newValue, () => socket.broadcast.emit(MessageStore.SetField.Message, newValue)); // broadcast set value to all other clients
+ if (newValue.type === Types.Text) {
+ // if the newValue has sring type, then it's suitable for searching -- pass it to SOLR
Search.updateDocument({ id: newValue.id, data: { set: (newValue as any).data } });
}
}
@@ -213,34 +208,36 @@ export namespace WebSocket {
Database.Instance.getDocuments(ids, callback);
}
- const suffixMap: { [type: string]: (string | [string, string | ((json: any) => any)]) } = {
- "number": "_n",
- "string": "_t",
- "boolean": "_b",
- "image": ["_t", "url"],
- "video": ["_t", "url"],
- "pdf": ["_t", "url"],
- "audio": ["_t", "url"],
- "web": ["_t", "url"],
- "map": ["_t", "url"],
- "script": ["_t", value => value.script.originalScript],
- "RichTextField": ["_t", value => value.Text],
- "date": ["_d", value => new Date(value.date).toISOString()],
- "proxy": ["_i", "fieldId"],
- "list": ["_l", list => {
- const results = [];
- for (const value of list.fields) {
- const term = ToSearchTerm(value);
- if (term) {
- results.push(term.value);
+ const suffixMap: { [type: string]: string | [string, string | ((json: any) => any)] } = {
+ number: '_n',
+ string: '_t',
+ boolean: '_b',
+ image: ['_t', 'url'],
+ video: ['_t', 'url'],
+ pdf: ['_t', 'url'],
+ audio: ['_t', 'url'],
+ web: ['_t', 'url'],
+ map: ['_t', 'url'],
+ script: ['_t', value => value.script.originalScript],
+ RichTextField: ['_t', value => value.Text],
+ date: ['_d', value => new Date(value.date).toISOString()],
+ proxy: ['_i', 'fieldId'],
+ list: [
+ '_l',
+ list => {
+ const results = [];
+ for (const value of list.fields) {
+ const term = ToSearchTerm(value);
+ if (term) {
+ results.push(term.value);
+ }
}
- }
- return results.length ? results : null;
- }]
+ return results.length ? results : null;
+ },
+ ],
};
- function ToSearchTerm(val: any): { suffix: string, value: any } | undefined {
-
+ function ToSearchTerm(val: any): { suffix: string; value: any } | undefined {
if (val === null || val === undefined) {
return;
}
@@ -252,69 +249,79 @@ export namespace WebSocket {
}
if (Array.isArray(suffix)) {
const accessor = suffix[1];
- if (typeof accessor === "function") {
+ if (typeof accessor === 'function') {
val = accessor(val);
} else {
val = val[accessor];
-
}
suffix = suffix[0];
-
}
return { suffix, value: val };
}
function getSuffix(value: string | [string, any]): string {
- return typeof value === "string" ? value : value[0];
+ return typeof value === 'string' ? value : value[0];
}
function addToListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
- diff.diff.$set = diff.diff.$addToSet; delete diff.diff.$addToSet;// convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones
+ diff.diff.$set = diff.diff.$addToSet;
+ delete diff.diff.$addToSet; // convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones
const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
const newListItems = diff.diff.$set[updatefield]?.fields;
if (!newListItems) {
- console.log("Error: addToListField - no new list items");
+ console.log('Error: addToListField - no new list items');
return;
}
- const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields.filter((item: any) => item !== undefined) || [];
- diff.diff.$set[updatefield].fields = [...curList, ...newListItems];//, ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
+ const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((item: any) => item !== undefined) || [];
+ diff.diff.$set[updatefield].fields = [...curList, ...newListItems]; //, ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))];
const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
delete diff.diff.length;
- Database.Instance.update(diff.id, diff.diff,
+ Database.Instance.update(
+ diff.id,
+ diff.diff,
() => {
if (sendBack) {
- console.log("Warning: list modified during update. Composite list is being returned.");
+ console.log('Warning: list modified during update. Composite list is being returned.');
const id = socket.id;
- socket.id = "";
+ socket.id = '';
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
socket.id = id;
} else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
dispatchNextOp(diff.id);
- }, false);
+ },
+ false
+ );
}
function remFromListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
- diff.diff.$set = diff.diff.$remFromSet; delete diff.diff.$remFromSet;
+ diff.diff.$set = diff.diff.$remFromSet;
+ delete diff.diff.$remFromSet;
const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
const remListItems = diff.diff.$set[updatefield].fields;
- const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields.filter((f: any) => f !== null) || [];
- diff.diff.$set[updatefield].fields = curList?.filter((curItem: any) => !remListItems.some((remItem: any) => remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem));
+ const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((f: any) => f !== null) || [];
+ diff.diff.$set[updatefield].fields = curList?.filter(
+ (curItem: any) => !remListItems.some((remItem: any) => (remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))
+ );
const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
delete diff.diff.length;
- Database.Instance.update(diff.id, diff.diff,
+ Database.Instance.update(
+ diff.id,
+ diff.diff,
() => {
if (sendBack) {
- console.log("SEND BACK");
+ console.log('SEND BACK');
const id = socket.id;
- socket.id = "";
+ socket.id = '';
socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
socket.id = id;
} else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
dispatchNextOp(diff.id);
- }, false);
+ },
+ false
+ );
}
- const pendingOps = new Map<string, { diff: Diff, socket: Socket }[]>();
+ const pendingOps = new Map<string, { diff: Diff; socket: Socket }[]>();
function dispatchNextOp(id: string) {
const next = pendingOps.get(id)!.shift();
@@ -341,7 +348,7 @@ export namespace WebSocket {
function UpdateField(socket: Socket, diff: Diff) {
if (CurUser !== socketMap.get(socket)) {
CurUser = socketMap.get(socket);
- console.log("Switch User: " + CurUser);
+ console.log('Switch User: ' + CurUser);
}
if (pendingOps.has(diff.id)) {
pendingOps.get(diff.id)!.push({ diff, socket });
@@ -357,24 +364,25 @@ export namespace WebSocket {
return GetRefFieldLocal([diff.id, (result?: Transferable) => SetField(socket, diff, result)]);
}
function SetField(socket: Socket, diff: Diff, curListItems?: Transferable) {
- Database.Instance.update(diff.id, diff.diff,
- () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false);
+ Database.Instance.update(diff.id, diff.diff, () => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false);
const docfield = diff.diff.$set || diff.diff.$unset;
if (docfield) {
const update: any = { id: diff.id };
let dynfield = false;
for (let key in docfield) {
- if (!key.startsWith("fields.")) continue;
+ if (!key.startsWith('fields.')) continue;
dynfield = true;
const val = docfield[key];
key = key.substring(7);
- Object.values(suffixMap).forEach(suf => { update[key + getSuffix(suf)] = { set: null }; });
+ Object.values(suffixMap).forEach(suf => {
+ update[key + getSuffix(suf)] = { set: null };
+ });
const term = ToSearchTerm(val);
if (term !== undefined) {
const { suffix, value } = term;
update[key + suffix] = { set: value };
if (key.endsWith('lastModified')) {
- update["lastModified" + suffix] = value;
+ update['lastModified' + suffix] = value;
}
}
}
@@ -403,6 +411,4 @@ export namespace WebSocket {
function CreateField(newValue: any) {
Database.Instance.insert(newValue);
}
-
}
-