upgrading session

This commit is contained in:
Andrew Gundersen 2021-03-22 20:35:22 -05:00
commit 4b3023fd4c
9 changed files with 288 additions and 105 deletions

View file

@ -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
});
}

View file

@ -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.

View file

@ -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";
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;
// Handle messages from server.
const onServerMessage = (data: string): void => {
const message = JSON.parse(data)
const onAuthSession = async (e: any, payload: string | Creds) => {
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
}
}
// 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));
}

View file

@ -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)) {

View file

@ -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);

View file

@ -96,8 +96,13 @@ export default function useMessages() {
}
const resetMessages = () => {
messages.value.clear()
}
return {
messages,
updateMessageView
updateMessageView,
resetMessages
}
}

130
src/modules/ws.ts Normal file
View file

@ -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);
}

View file

@ -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" });
}

View file

@ -1 +1 @@
{"w":735,"h":510,"x":944,"y":489}
{"w":350,"h":699,"x":649,"y":168}