192 lines
No EOL
4.5 KiB
TypeScript
192 lines
No EOL
4.5 KiB
TypeScript
"use strict";
|
|
|
|
import WebSocket from 'ws';
|
|
import { backgroundMitt } from './emitter';
|
|
import { ipcMain } from "electron";
|
|
import { play } from './audio';
|
|
|
|
import {
|
|
AuthMessage,
|
|
Profile,
|
|
Annotation,
|
|
StandardMessage,
|
|
ClientMessage
|
|
} from "@/types/message/index";
|
|
|
|
import { clientMessage, renderMessage } from '@/modules/message';
|
|
|
|
const ip = 'ws://127.0.0.1';
|
|
const port = 8760;
|
|
const reconnectTimeout = 3000; //ms
|
|
let socket: WebSocket;
|
|
let success = false;
|
|
let auth = false;
|
|
|
|
const onAuthSession = async (e: any, token: string) => {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
console.log('Authenticating...');
|
|
|
|
// Handle auth response from server.
|
|
backgroundMitt.once('auth-res', (res: string) => {
|
|
|
|
if (res == "locked") {
|
|
reject(res);
|
|
} else {
|
|
console.log('Success!');
|
|
auth = true;
|
|
resolve(res);
|
|
}
|
|
|
|
});
|
|
|
|
if (token) {
|
|
socket.send(token);
|
|
} else {
|
|
socket.send("no-token");
|
|
}
|
|
|
|
});
|
|
};
|
|
|
|
|
|
//---Message Handlers-----------------------------------------------
|
|
|
|
const handleAuthMessage = (message: string) => {
|
|
backgroundMitt.emit('auth-res', message);
|
|
}
|
|
|
|
const handleProfileMessage = (message: Profile) => {
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'update-profile',
|
|
message: message
|
|
});
|
|
}
|
|
|
|
const handleStandardMessage = (m: StandardMessage) => {
|
|
|
|
// Create a render message object.
|
|
const message = renderMessage(
|
|
m.content.text, m.content.audio, m.context, m.modifier);
|
|
|
|
// Play audio if any.
|
|
if (message.content.audio) {
|
|
const audioBytes = Buffer.from(m.content.audio as string, 'hex');
|
|
m.content.audio = true;
|
|
play(audioBytes);
|
|
}
|
|
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'render-message',
|
|
message: message
|
|
});
|
|
}
|
|
|
|
const handleAnnotationMessage = (message: Annotation) => {
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'annotate-message',
|
|
message: message
|
|
});
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
const onMessage = (messageStr: string): void => {
|
|
|
|
// Auth messages are strings.
|
|
if (!auth) handleAuthMessage(messageStr)
|
|
|
|
const message = JSON.parse(messageStr)
|
|
|
|
if (message.content) {
|
|
handleStandardMessage(message)
|
|
}
|
|
|
|
else if (message.first) {
|
|
handleProfileMessage(message)
|
|
}
|
|
|
|
else {
|
|
handleAnnotationMessage(message)
|
|
}
|
|
|
|
};
|
|
|
|
const onClientMessage = (e: any, payload: ClientMessage): void => {
|
|
console.log('sending message');
|
|
socket.send(JSON.stringify(payload));
|
|
}
|
|
|
|
const restart = () => {
|
|
auth = false;
|
|
initSession();
|
|
}
|
|
|
|
// Run every time we want to connect to backend.
|
|
export function initSession(): void {
|
|
|
|
// Close existing sockets.
|
|
if (socket) {
|
|
socket.removeAllListeners();
|
|
socket.terminate();
|
|
socket.close();
|
|
success = false;
|
|
}
|
|
|
|
// Init new socket.
|
|
socket = new WebSocket(`${ip}:${port}`);
|
|
socket.binaryType = 'arraybuffer';
|
|
|
|
// handle renderer auth-token event
|
|
ipcMain.removeHandler('auth-session'); // avoid setting duplicate handlers
|
|
ipcMain.handle('auth-session', onAuthSession);
|
|
|
|
// handle user message event
|
|
ipcMain.removeAllListeners('client-message');
|
|
ipcMain.on('client-message', onClientMessage);
|
|
|
|
// handle renderer logout event
|
|
ipcMain.removeAllListeners('logout');
|
|
ipcMain.on('logout', (_event, _payload: string) => restart());
|
|
|
|
// Connect to the backend.
|
|
socket.on('open', () => {
|
|
console.log('Connected to Crimata Servers.');
|
|
|
|
// call auth renderer event on connection
|
|
backgroundMitt.emit('ipc-renderer', {
|
|
endpoint: 'auth',
|
|
message: null
|
|
});
|
|
|
|
success = true;
|
|
|
|
});
|
|
|
|
// Handle for failed connect, try again.
|
|
socket.on('error', (_e) => {
|
|
console.log('ERROR: Failed to connect.');
|
|
socket.removeAllListeners();
|
|
socket.close();
|
|
setTimeout(() => {
|
|
if (!success) {
|
|
console.log('Reconnecting...');
|
|
initSession();
|
|
}
|
|
}, reconnectTimeout);
|
|
|
|
});
|
|
|
|
socket.on('close', () => {
|
|
console.log('Connection droped! Restarting...');
|
|
restart();
|
|
});
|
|
|
|
socket.on("message", onMessage);
|
|
}
|
|
|
|
export function sendAudio(audio: string, uid: string): void {
|
|
const m = clientMessage("", audio, uid);
|
|
socket.send(JSON.stringify(m));
|
|
} |