From 4b3023fd4cf0f8612563d2246d1f4ee90c5c8de9 Mon Sep 17 00:00:00 2001 From: Andrew Gundersen Date: Mon, 22 Mar 2021 20:35:22 -0500 Subject: [PATCH] upgrading session --- src/background/handlers.ts | 69 ++++++++ src/background/run.ts | 9 +- src/background/session.ts | 161 +++++++----------- .../inputItem/controllers/textCtrl.ts | 2 +- src/modules/auth.ts | 2 +- src/modules/messages.ts | 7 +- src/modules/ws.ts | 130 ++++++++++++++ src/views/login.vue | 11 +- windowState.json | 2 +- 9 files changed, 288 insertions(+), 105 deletions(-) create mode 100644 src/background/handlers.ts create mode 100644 src/modules/ws.ts diff --git a/src/background/handlers.ts b/src/background/handlers.ts new file mode 100644 index 0000000..4f3764b --- /dev/null +++ b/src/background/handlers.ts @@ -0,0 +1,69 @@ +import { backgroundMitt } from './emitter'; + +// Attempt an authenticaion, either with Token or with Creds. +const onAuthRequest = async (e: any, payload: string | Creds) => { + + 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 (typeof payload !== "string") { + payload = JSON.stringify(payload) + } + + // Send token to backend + socket.send(payload); + + }); +}; + + +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: 'render-message', + message: message + }); +} \ No newline at end of file diff --git a/src/background/run.ts b/src/background/run.ts index a007ad5..4c312d8 100644 --- a/src/background/run.ts +++ b/src/background/run.ts @@ -1,7 +1,7 @@ "use strict"; import { createWindow } from './window'; -import { initSession } from './session'; +import useWebSockets from './session'; import { initAudioIO } from './audio'; let socket = false; @@ -11,11 +11,16 @@ let socket = false; */ export async function main() { + const { initSession } = useWebSockets() + // create main window. await createWindow(); // Instantiate socket session with crimata-platorm. - if (!socket) initSession(); + if (!socket) { + initSocketSession(); + } + socket = true; // Begin audio stream. diff --git a/src/background/session.ts b/src/background/session.ts index 49ddb13..28787f4 100644 --- a/src/background/session.ts +++ b/src/background/session.ts @@ -1,28 +1,72 @@ -"use strict"; - -import WebSocket from 'ws'; import { backgroundMitt } from './emitter'; -import { ipcMain } from "electron"; -import { play } from './audio'; -import { - Creds, - Profile, - Annotation, - StandardMessage, - ClientMessage -} from "@/types/message/index"; +import { handleAuthMessage, handleStandardMessage, handleProfileMessage, handleAnnotation } from "./handlers"; + + +// Handle messages from server. +const onServerMessage = (data: string): void => { + const message = JSON.parse(data) + + if (message.key) { + handleAuthMessage(message) + } + + else if (message.content) { + handleStandardMessage(message) + } + + else if (message.first) { + handleProfileMessage(message) + } + + else { + handleAnnotationMessage(message) + } + +}; + +// Handle messages from client. +const onClientMessage = (_event: IpcMainEvent, payload: any) { + sendMessage(JSON.stringify(payload)) +} + +export default function agentInterface() { + + const { createSocket, sendMessage } = useWebSockets(onServerMessage) + + const initSession = () => { + + ipcMain.removeAllListeners() + ipcMain.removeHandler('auth-session'); + + ipcMain.handle('auth-request', onAuthRequest); + ipcMain.on('client-message', onClientMessage); + + createSocket() + } + + return { + initSession + } + +} + + + + + -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, payload: string | Creds) => { + + + + + + + +// Attempt an authenticaion, either with Token or with Creds. +const onAuthRequest = async (e: any, payload: string | Creds) => { return new Promise((resolve, reject) => { @@ -52,8 +96,6 @@ const onAuthSession = async (e: any, payload: string | Creds) => { }; -//---Message Handlers----------------------------------------------- - const handleAuthMessage = (message: string) => { backgroundMitt.emit('auth-res', message); } @@ -91,8 +133,6 @@ const handleAnnotationMessage = (message: Annotation) => { }); } -//------------------------------------------------------------------ - const onMessage = (messageStr: string): void => { // Auth messages are strings. @@ -122,77 +162,4 @@ const onMessage = (messageStr: string): void => { 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.'); - - // Try to authenticate token right away. - 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)); } \ No newline at end of file diff --git a/src/components/inputItem/controllers/textCtrl.ts b/src/components/inputItem/controllers/textCtrl.ts index ce3a552..18d686a 100644 --- a/src/components/inputItem/controllers/textCtrl.ts +++ b/src/components/inputItem/controllers/textCtrl.ts @@ -97,7 +97,7 @@ export default function useTextInputController(elementX: Ref) { } } - // Keys that are capable of opening the text input. + // Keys that are capable of opening the text input (numbers and letters). const hotKeyRange = keyboardNameMap.slice(47, 91) const isHotKey = (key: string) => { if (hotKeyRange.includes(key)) { diff --git a/src/modules/auth.ts b/src/modules/auth.ts index f1481f2..3430cf2 100644 --- a/src/modules/auth.ts +++ b/src/modules/auth.ts @@ -23,7 +23,7 @@ if (token) { // Load key and invoke onAuthSession to try key-login. const authToken = async () => { - console.log("Calling auth token.") + console.log("Calling auth token!!") const { invoke } = useIpc(); try { token = window.localStorage.getItem(AUTH_KEY); diff --git a/src/modules/messages.ts b/src/modules/messages.ts index 2dcaf00..4b0c8b7 100644 --- a/src/modules/messages.ts +++ b/src/modules/messages.ts @@ -96,8 +96,13 @@ export default function useMessages() { } + const resetMessages = () => { + messages.value.clear() + } + return { messages, - updateMessageView + updateMessageView, + resetMessages } } \ No newline at end of file diff --git a/src/modules/ws.ts b/src/modules/ws.ts new file mode 100644 index 0000000..c487573 --- /dev/null +++ b/src/modules/ws.ts @@ -0,0 +1,130 @@ +"use strict"; + +import WebSocket from 'ws'; +import { ipcMain } from "electron"; + +let socket: WebSocket; + + +// Run every time we want to connect to backend. +export default function useWebSockets(receiveCallback: (s: Buffer) => any) { + + const sendMessage = (data: string) => { + + console.log("Sending message: ", data) + + socket.send(data) + + } + + const onOpen = (event: WebSocket.OpenEvent) => { + + console.log('Connected to Server!'); + + } + + const onServerMessage = (event: WebSocket.MessageEvent) => { + + console.log('Message received: ', event); + + receiveCallback(event.data) + + } + + const onClose = (event: WebSocket.CloseEvent) => { + console.log("socket closed normally.") + } + + const onError = (event: WebSocket.ErrorEvent) => { + console.log('WebSocket error: ', event); + + console.log("Reconnecting...") + createSocket() + } + + const createSocket = () => { + socket = new WebSocket(`ws://127.0.0.1:8760`) + + // Add listeners. + socket.addEventListener("open", onOpen) + socket.addEventListener("message", onServerMessage) + socket.addEventListener("close", onClose) + socket.addEventListener("error", createSocket) + + console.log("New socket created.") + } + + return { + createSocket + } + +} + + + + + + + + + // Close existing sockets. + if (socket) { + socket.removeAllListeners(); + socket.terminate(); + socket.close(); + success = false; + } + + // Init new socket. + socket = new WebSocket(`ws://127.0.0.1:8760`); + socket.binaryType = 'arraybuffer'; + + // Handle requests for authentication (promise). + 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.'); + + // Try to authenticate token right away. + backgroundMitt.emit('ipc-renderer', { + endpoint: 'auth', + message: null + }); + + success = true; + + }); + + // Error handling. + socket.on('error', (_e) => { + + console.log('ERROR: Failed to connect.'); + socket.removeAllListeners(); + socket.close(); + + setTimeout(() => { + if (!success) { + console.log('Reconnecting...'); + initSession(); + } + }, 3000); // reconnect timeout + + }); + + socket.on('close', () => { + console.log('Connection droped! Restarting...'); + restart(); + }); + + socket.on("message", onMessage); +} \ No newline at end of file diff --git a/src/views/login.vue b/src/views/login.vue index cba4b85..53e335f 100644 --- a/src/views/login.vue +++ b/src/views/login.vue @@ -41,6 +41,7 @@ import { defineComponent, ref } from "vue"; import { useAuth } from "@/modules/auth"; import { useIpc } from "@/modules/ipc"; import { useRouter } from "vue-router"; +import useMessages from "@/modules/messages"; export default defineComponent({ name: "Login", @@ -48,6 +49,7 @@ export default defineComponent({ setup() { const { setToken } = useAuth(); + const { resetMessages } = useMessages(); const router = useRouter(); const email = ref(""); @@ -65,8 +67,13 @@ export default defineComponent({ }; try { - const res = await invoke('auth-session', payload); - setToken(res); + const response = await invoke('auth-session', payload); + + // On login without token, we clear localStorage and messages. + window.localStorage.clear(); + resetMessages(); + + setToken(response); invalid.value = false; router.push({ name: "home" }); } diff --git a/windowState.json b/windowState.json index a9fec30..6e4a7d7 100644 --- a/windowState.json +++ b/windowState.json @@ -1 +1 @@ -{"w":735,"h":510,"x":944,"y":489} \ No newline at end of file +{"w":350,"h":699,"x":649,"y":168} \ No newline at end of file -- 2.43.0