diff options
| author | Melonai <einebeere@gmail.com> | 2021-05-31 01:47:38 +0200 |
|---|---|---|
| committer | Melonai <einebeere@gmail.com> | 2021-05-31 01:47:38 +0200 |
| commit | 8f1f90c3e7d836a23f1cd09617c2a0fcfac3f3f4 (patch) | |
| tree | 7359e054d13a054a661c1584dae20d0698fc4c84 /assets/src | |
| parent | e0cabfea7c7b442acd3636e7495958b87e253176 (diff) | |
| download | rook-8f1f90c3e7d836a23f1cd09617c2a0fcfac3f3f4.tar.zst rook-8f1f90c3e7d836a23f1cd09617c2a0fcfac3f3f4.zip | |
Socket connection with managed state
Diffstat (limited to 'assets/src')
| -rw-r--r-- | assets/src/components/IncomingRequests.svelte | 17 | ||||
| -rw-r--r-- | assets/src/components/Request.svelte | 10 | ||||
| -rw-r--r-- | assets/src/network/channel/connection.ts | 69 | ||||
| -rw-r--r-- | assets/src/network/channel/request.ts | 14 | ||||
| -rw-r--r-- | assets/src/network/channel/share.ts | 17 | ||||
| -rw-r--r-- | assets/src/network/channel/socket.ts | 59 | ||||
| -rw-r--r-- | assets/src/network/socket.ts | 44 |
7 files changed, 170 insertions, 60 deletions
diff --git a/assets/src/components/IncomingRequests.svelte b/assets/src/components/IncomingRequests.svelte index 1db50af..bf08ffe 100644 --- a/assets/src/components/IncomingRequests.svelte +++ b/assets/src/components/IncomingRequests.svelte @@ -1,18 +1,17 @@ <script lang="ts"> - import { getToken, joinShareChannel } from "../network/socket"; + import { getOwnToken, start, Type } from "../network/channel/connection"; + import requests from "../stores/requests"; - const startConnection = async () => { - const token = await getToken(); - joinShareChannel(token); - return token; - }; + const startPromise = start(Type.SHARE); + + // TODO: Switch to store-based state updates. </script> -{#await startConnection()} +{#await startPromise} <h3>Fetching token...</h3> -{:then token} - <h3>Your token is <b>{token}</b>.</h3> +{:then} + <h3>Your token is <b>{getOwnToken()}</b>.</h3> {#each $requests as request} <p>{JSON.stringify(request)}</p> diff --git a/assets/src/components/Request.svelte b/assets/src/components/Request.svelte index 134c4d5..0c0b111 100644 --- a/assets/src/components/Request.svelte +++ b/assets/src/components/Request.svelte @@ -1,13 +1,9 @@ <script lang="ts"> - import { getToken, joinRequestChannel } from "../network/socket"; - import getShareToken from "../utils/getShareToken"; + import { start, Type } from "../network/channel/connection"; - const startConnection = async () => { - const token = await getToken(); - joinRequestChannel(token, getShareToken()); - }; + // TODO: Switch to store-based state updates. - startConnection(); + start(Type.REQUEST); </script> <main> diff --git a/assets/src/network/channel/connection.ts b/assets/src/network/channel/connection.ts new file mode 100644 index 0000000..52d85d1 --- /dev/null +++ b/assets/src/network/channel/connection.ts @@ -0,0 +1,69 @@ +import { Channel, Push, Socket } from "phoenix"; +import { startRequest } from "./request"; +import { startShare } from "./share"; +import { connectSocket, fetchToken } from "./socket"; + +export enum Type { + NONE, + REQUEST, + SHARE, +} + +enum ConnectionState { + CONNECTING_SOCKET, + FETCHING_TOKEN, + CONNECTING_CHANNEL, + + CONNECTED, +} + +export type Connection = { + socket: Socket; + channel: Channel | null; + token: string | null; + state: ConnectionState; + type: Type; +}; + +const connection: Connection = { + socket: new Socket("/socket", {}), + channel: null, + token: null, + state: ConnectionState.CONNECTING_SOCKET, + type: Type.NONE, +}; + +export async function start(type: Type.REQUEST | Type.SHARE) { + connection.type = type; + + await connectSocket(connection.socket); + + updateState(ConnectionState.FETCHING_TOKEN); + connection.token = await fetchToken(connection.socket); + + updateState(ConnectionState.CONNECTING_CHANNEL); + type === Type.SHARE + ? await startShare(connection) + : await startRequest(connection); +} + +export function send(event: string, data: any): Push { + if (connection.state !== ConnectionState.CONNECTED) { + throw new Error("There is no connection yet."); + } + + return connection.channel.push(event, data); +} + +export function getOwnToken(): string { + if (connection.state <= ConnectionState.FETCHING_TOKEN) { + throw new Error("There is no token yet."); + } + + return connection.token; +} + +function updateState(state: ConnectionState) { + // TODO: Notify state listeners + connection.state = state; +} diff --git a/assets/src/network/channel/request.ts b/assets/src/network/channel/request.ts new file mode 100644 index 0000000..801eee1 --- /dev/null +++ b/assets/src/network/channel/request.ts @@ -0,0 +1,14 @@ +import getShareToken from "../../utils/getShareToken"; +import type { Connection } from "./connection"; +import { joinRequestChannel } from "./socket"; + +export async function startRequest(connection: Connection) { + const requestChannel = await joinRequestChannel( + connection.socket, + connection.token, + getShareToken() + ); + connection.channel = requestChannel; + + // TODO: Handle incoming messages from the request channel +} diff --git a/assets/src/network/channel/share.ts b/assets/src/network/channel/share.ts new file mode 100644 index 0000000..10a34fa --- /dev/null +++ b/assets/src/network/channel/share.ts @@ -0,0 +1,17 @@ +import requests from "../../stores/requests"; +import type { Connection } from "./connection"; +import { joinShareChannel } from "./socket"; + +export async function startShare(connection: Connection) { + const shareChannel = await joinShareChannel( + connection.socket, + connection.token + ); + connection.channel = shareChannel; + + shareChannel.on("new_request", onNewRequest); +} + +function onNewRequest(data) { + requests.addRequest(data); +} diff --git a/assets/src/network/channel/socket.ts b/assets/src/network/channel/socket.ts new file mode 100644 index 0000000..7d14842 --- /dev/null +++ b/assets/src/network/channel/socket.ts @@ -0,0 +1,59 @@ +import type { Channel, Socket } from "phoenix"; + +export function connectSocket(socket: Socket): Promise<void> { + return new Promise((resolve, _reject) => { + socket.connect(); + socket.onOpen(() => { + resolve(); + }); + }); +} + +export function fetchToken(socket: Socket): Promise<string> { + let tokenChannel = socket.channel("token", {}); + return new Promise((resolve, reject) => { + tokenChannel + .join() + .receive("ok", () => { + tokenChannel + .push("get_token", {}, 5000) + .receive("ok", ({ token }) => resolve(token)) + .receive("error", err => reject(err)) + .receive("timeout", err => reject(err)); + }) + .receive("error", err => reject(err)); + }); +} + +export function joinShareChannel( + socket: Socket, + token: string +): Promise<Channel> { + return joinChannel(socket, `share:${token}`); +} + +export function joinRequestChannel( + socket: Socket, + request_token: string, + share_token: string +): Promise<Channel> { + return joinChannel(socket, `request:${request_token}`, { + share: share_token, + }); +} + +function joinChannel( + socket: Socket, + topic: string, + opts?: object +): Promise<Channel> { + let channel = socket.channel(topic, opts); + + return new Promise((resolve, reject) => { + channel + .join() + .receive("ok", () => resolve(channel)) + .receive("error", err => reject(err)) + .receive("timeout", err => reject(err)); + }); +} diff --git a/assets/src/network/socket.ts b/assets/src/network/socket.ts deleted file mode 100644 index 87f5b7c..0000000 --- a/assets/src/network/socket.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Socket } from "phoenix"; -import requests from "../stores/requests"; - -let socket = new Socket("/socket", {}); -socket.connect(); - -export const getToken: () => Promise<string> = () => { - let tokenChannel = socket.channel("token", {}); - return new Promise((resolve, reject) => { - tokenChannel - .join() - .receive("ok", () => { - tokenChannel - .push("get_token", {}, 5000) - .receive("ok", ({ token }) => resolve(token)) - .receive("error", err => reject(err)) - .receive("timeout", err => reject(err)); - }) - .receive("error", err => reject(err)); - }); -}; - -export const joinShareChannel = token => { - let shareChannel = socket.channel(`share:${token}`); - - shareChannel.on("new_request", requests.addRequest); - - shareChannel - .join() - .receive("error", err => - console.log("Failed joining share channel: " + JSON.stringify(err)) - ); -}; - -export const joinRequestChannel = (token, share) => { - let requestChannel = socket.channel(`request:${token}`, { share }); - - requestChannel - .join() - .receive("ok", () => console.log("Connected to request!")) - .receive("error", err => - console.log("Failed joining request channel:" + JSON.stringify(err)) - ); -}; |
