add mailboxes
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
|||||||
getWebSocketStats,
|
getWebSocketStats,
|
||||||
processMessage,
|
processMessage,
|
||||||
reconnectServers,
|
reconnectServers,
|
||||||
|
removeExpiredMailboxes,
|
||||||
trackConnection,
|
trackConnection,
|
||||||
} from "./websocket-handler";
|
} from "./websocket-handler";
|
||||||
import {
|
import {
|
||||||
@@ -138,8 +139,11 @@ async function main() {
|
|||||||
|
|
||||||
// LOOP
|
// LOOP
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
if (process.env.DEV != "1") {
|
||||||
updateCLI();
|
updateCLI();
|
||||||
reconnectServers(config);
|
reconnectServers(config);
|
||||||
|
}
|
||||||
|
removeExpiredMailboxes();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
// FINISH
|
// FINISH
|
||||||
|
|||||||
Binary file not shown.
Vendored
+58
-4
@@ -131,6 +131,19 @@
|
|||||||
);
|
);
|
||||||
return proxyState;
|
return proxyState;
|
||||||
}
|
}
|
||||||
|
function persistState(localStorageKey, state) {
|
||||||
|
state.subscribe(() => {
|
||||||
|
const stringifiedValue = state.toString();
|
||||||
|
localStorage.setItem(localStorageKey, stringifiedValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function restoreState(localStorageKey, initialStateValue) {
|
||||||
|
const storedString = localStorage.getItem(localStorageKey) ?? JSON.stringify(initialStateValue);
|
||||||
|
const convertedValue = JSON.parse(storedString);
|
||||||
|
const state = new State(convertedValue);
|
||||||
|
persistState(localStorageKey, state);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
function createElement(tagName, attributes = {}, ...children) {
|
function createElement(tagName, attributes = {}, ...children) {
|
||||||
const element = document.createElement(tagName);
|
const element = document.createElement(tagName);
|
||||||
if (attributes != null)
|
if (attributes != null)
|
||||||
@@ -159,13 +172,13 @@
|
|||||||
try {
|
try {
|
||||||
const [listState, toElement] = value;
|
const [listState, toElement] = value;
|
||||||
listState.handleAddition((newItem) => {
|
listState.handleAddition((newItem) => {
|
||||||
const child = toElement(newItem, listState);
|
const child = toElement(newItem);
|
||||||
listState.handleRemoval(
|
listState.handleRemoval(
|
||||||
newItem,
|
newItem,
|
||||||
() => child.remove()
|
() => child.remove()
|
||||||
);
|
);
|
||||||
element.append(child);
|
element.append(child);
|
||||||
child.scrollIntoView();
|
element.scrollTop = element.scrollHeight;
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
throw `error: cannot process subscribe:children directive because ListItemConverter is not defined. Usage: "subscribe:children={[list, converter]}"; you can find a more detailed example in the documentation`;
|
throw `error: cannot process subscribe:children directive because ListItemConverter is not defined. Usage: "subscribe:children={[list, converter]}"; you can find a more detailed example in the documentation`;
|
||||||
@@ -225,6 +238,8 @@
|
|||||||
};
|
};
|
||||||
messageHandler = (data) => {
|
messageHandler = (data) => {
|
||||||
};
|
};
|
||||||
|
mailboxHandler = (mailboxId2) => {
|
||||||
|
};
|
||||||
// init
|
// init
|
||||||
set onconnect(handler) {
|
set onconnect(handler) {
|
||||||
this.connectionHandler = handler;
|
this.connectionHandler = handler;
|
||||||
@@ -235,6 +250,9 @@
|
|||||||
set onmessage(handler) {
|
set onmessage(handler) {
|
||||||
this.messageHandler = handler;
|
this.messageHandler = handler;
|
||||||
}
|
}
|
||||||
|
set onmailbox(handler) {
|
||||||
|
this.mailboxHandler = handler;
|
||||||
|
}
|
||||||
// utility methods
|
// utility methods
|
||||||
send(messageObject) {
|
send(messageObject) {
|
||||||
if (this.ws == void 0) return false;
|
if (this.ws == void 0) return false;
|
||||||
@@ -244,15 +262,23 @@
|
|||||||
}
|
}
|
||||||
// public methods
|
// public methods
|
||||||
connect(address) {
|
connect(address) {
|
||||||
|
this.disconnect();
|
||||||
this.ws = new WebSocket(address);
|
this.ws = new WebSocket(address);
|
||||||
this.ws.addEventListener("open", this.connectionHandler);
|
this.ws.addEventListener("open", this.connectionHandler);
|
||||||
this.ws.addEventListener("close", this.disconnectionHandler);
|
this.ws.addEventListener("close", this.disconnectionHandler);
|
||||||
this.ws.addEventListener("message", (message) => {
|
this.ws.addEventListener("message", (message) => {
|
||||||
const dataString = message.data.toString();
|
const dataString = message.data.toString();
|
||||||
const data = JSON.parse(dataString);
|
const data = JSON.parse(dataString);
|
||||||
|
if (data.assignedMailboxId) {
|
||||||
|
return this.mailboxHandler(data.assignedMailboxId);
|
||||||
|
} else {
|
||||||
this.messageHandler(data);
|
this.messageHandler(data);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
disconnect() {
|
||||||
|
this.ws?.close();
|
||||||
|
}
|
||||||
sendMessage(channel, body) {
|
sendMessage(channel, body) {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
messageChannel: channel,
|
messageChannel: channel,
|
||||||
@@ -272,10 +298,24 @@
|
|||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
requestMailbox() {
|
||||||
|
const messageObject = {
|
||||||
|
requestingMailboxSetup: true
|
||||||
|
};
|
||||||
|
return this.send(messageObject);
|
||||||
|
}
|
||||||
|
accessMailbox(mailboxId2) {
|
||||||
|
const messageObject = {
|
||||||
|
requestedMailbox: mailboxId2
|
||||||
|
};
|
||||||
|
return this.send(messageObject);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/translations.tsx
|
// src/translations.tsx
|
||||||
var staticTextEnglish = {
|
var staticTextEnglish = {
|
||||||
|
mailbox: "Mailbox",
|
||||||
|
requestMailbox: "Request Mailbox",
|
||||||
channel: "Channel",
|
channel: "Channel",
|
||||||
channel_placeholder: "my-channel",
|
channel_placeholder: "my-channel",
|
||||||
disconnected: "Server disconnected",
|
disconnected: "Server disconnected",
|
||||||
@@ -298,6 +338,8 @@
|
|||||||
var translations = {
|
var translations = {
|
||||||
en: staticTextEnglish,
|
en: staticTextEnglish,
|
||||||
es: {
|
es: {
|
||||||
|
mailbox: "Buz\xF3n",
|
||||||
|
requestMailbox: "Solicitar buz\xF3n",
|
||||||
channel: "Canal",
|
channel: "Canal",
|
||||||
channel_placeholder: "mi-canal",
|
channel_placeholder: "mi-canal",
|
||||||
disconnected: "Sin coneci\xF3n",
|
disconnected: "Sin coneci\xF3n",
|
||||||
@@ -318,6 +360,8 @@
|
|||||||
unsubscribe: "Cancelar"
|
unsubscribe: "Cancelar"
|
||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
|
mailbox: "Briefkasten",
|
||||||
|
requestMailbox: "Briefkasten beantragen",
|
||||||
channel: "Kanal",
|
channel: "Kanal",
|
||||||
channel_placeholder: "mein-kanal",
|
channel_placeholder: "mein-kanal",
|
||||||
disconnected: "Verbindung getrennt",
|
disconnected: "Verbindung getrennt",
|
||||||
@@ -352,12 +396,15 @@
|
|||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
uuid = new UUID();
|
id = UUID();
|
||||||
};
|
};
|
||||||
var UDN = new UDNFrontend();
|
var UDN = new UDNFrontend();
|
||||||
UDN.onconnect = () => {
|
UDN.onconnect = () => {
|
||||||
isDisconnected.value = false;
|
isDisconnected.value = false;
|
||||||
updateStats();
|
updateStats();
|
||||||
|
if (mailboxId.value != "") {
|
||||||
|
UDN.accessMailbox(mailboxId.value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
UDN.onmessage = (data) => {
|
UDN.onmessage = (data) => {
|
||||||
lastReceivedMessage.value = JSON.stringify(data, null, 4);
|
lastReceivedMessage.value = JSON.stringify(data, null, 4);
|
||||||
@@ -367,6 +414,9 @@
|
|||||||
if (messageBody) messages.add(messageObject);
|
if (messageBody) messages.add(messageObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
UDN.onmailbox = (id) => {
|
||||||
|
mailboxId.value = id;
|
||||||
|
};
|
||||||
UDN.ondisconnect = () => {
|
UDN.ondisconnect = () => {
|
||||||
isDisconnected.value = true;
|
isDisconnected.value = true;
|
||||||
setTimeout(connect, 2e3);
|
setTimeout(connect, 2e3);
|
||||||
@@ -376,6 +426,7 @@
|
|||||||
}
|
}
|
||||||
connect();
|
connect();
|
||||||
var isDisconnected = new State(true);
|
var isDisconnected = new State(true);
|
||||||
|
var mailboxId = restoreState("mailbox-id", "");
|
||||||
var messages = new ListState();
|
var messages = new ListState();
|
||||||
var lastReceivedMessage = new State(
|
var lastReceivedMessage = new State(
|
||||||
getText("noMessagesReceived")
|
getText("noMessagesReceived")
|
||||||
@@ -411,6 +462,9 @@
|
|||||||
UDN.sendMessage(newMessageChannel.value, newMessageBody.value);
|
UDN.sendMessage(newMessageChannel.value, newMessageBody.value);
|
||||||
newMessageBody.value = "";
|
newMessageBody.value = "";
|
||||||
}
|
}
|
||||||
|
function requestMailbox() {
|
||||||
|
UDN.requestMailbox();
|
||||||
|
}
|
||||||
|
|
||||||
// src/infoScreen.tsx
|
// src/infoScreen.tsx
|
||||||
function InfoScreen() {
|
function InfoScreen() {
|
||||||
@@ -419,7 +473,7 @@
|
|||||||
|
|
||||||
// src/mainScreen.tsx
|
// src/mainScreen.tsx
|
||||||
function MainScreen() {
|
function MainScreen() {
|
||||||
return /* @__PURE__ */ createElement("article", { id: "main-screen" }, /* @__PURE__ */ createElement("header", null, getText("settings")), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("messageLastReceived")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": lastReceivedMessage }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("subscribeToChannel")), /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("article", { id: "main-screen" }, /* @__PURE__ */ createElement("header", null, getText("settings")), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("messageLastReceived")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": lastReceivedMessage }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("mailbox")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": mailboxId }))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement("button", { class: "primary width-100", "on:click": requestMailbox }, getText("requestMailbox"), /* @__PURE__ */ createElement("span", { class: "icon" }, "inbox"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("subscribeToChannel")), /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
placeholder: getText("channel_placeholder"),
|
placeholder: getText("channel_placeholder"),
|
||||||
|
|||||||
+18
@@ -21,6 +21,7 @@ touch src/index.tsx dist/index.html
|
|||||||
```
|
```
|
||||||
|
|
||||||
The following build script will be enough:
|
The following build script will be enough:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -102,6 +103,7 @@ listState.remove(newItem);
|
|||||||
## Persistence
|
## Persistence
|
||||||
|
|
||||||
States can persist through reloads via LocalStorage. To implement this, modify your code like this:
|
States can persist through reloads via LocalStorage. To implement this, modify your code like this:
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
-const myState = new React.State("hello");
|
-const myState = new React.State("hello");
|
||||||
+const myState = React.restoreState("my-state", "hello");
|
+const myState = React.restoreState("my-state", "hello");
|
||||||
@@ -213,44 +215,60 @@ document.body.append(
|
|||||||
```
|
```
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 1.1.0
|
## 1.1.0
|
||||||
|
|
||||||
- Improve code
|
- Improve code
|
||||||
- Add missing `break` statements for directives
|
- Add missing `break` statements for directives
|
||||||
- Add `toggle` directive
|
- Add `toggle` directive
|
||||||
- Improve documentation
|
- Improve documentation
|
||||||
|
|
||||||
## 1.1.1
|
## 1.1.1
|
||||||
|
|
||||||
- Improve documentation
|
- Improve documentation
|
||||||
|
|
||||||
## 1.1.2
|
## 1.1.2
|
||||||
|
|
||||||
- Remove `console.log()` calls
|
- Remove `console.log()` calls
|
||||||
- Improve documentation
|
- Improve documentation
|
||||||
|
|
||||||
## 1.1.3
|
## 1.1.3
|
||||||
|
|
||||||
- Add `on:enter` directive
|
- Add `on:enter` directive
|
||||||
|
|
||||||
## 1.2.0
|
## 1.2.0
|
||||||
|
|
||||||
**BREAKING CHANGES**
|
**BREAKING CHANGES**
|
||||||
|
|
||||||
- Replace UUID class with function;
|
- Replace UUID class with function;
|
||||||
- `new UUID()` => `UUID() returns string`
|
- `new UUID()` => `UUID() returns string`
|
||||||
- Replace definition of `Identifiable`
|
- Replace definition of `Identifiable`
|
||||||
- now has `id: string` instead of `uuid: UUID()`
|
- now has `id: string` instead of `uuid: UUID()`
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
|
|
||||||
- Add State persistence
|
- Add State persistence
|
||||||
- Add error description when utilizing `subscribe:children` incorrectly
|
- Add error description when utilizing `subscribe:children` incorrectly
|
||||||
- Fix bug where ListState subscriptions were not called
|
- Fix bug where ListState subscriptions were not called
|
||||||
- Improve documentation
|
- Improve documentation
|
||||||
|
|
||||||
## 1.2.1
|
## 1.2.1
|
||||||
|
|
||||||
- Add `set:<attribute>` directive
|
- Add `set:<attribute>` directive
|
||||||
|
|
||||||
## 1.2.2
|
## 1.2.2
|
||||||
|
|
||||||
- Remove list parameter from `ListItemConverter`
|
- Remove list parameter from `ListItemConverter`
|
||||||
- Add `clear()` method to `ListState`
|
- Add `clear()` method to `ListState`
|
||||||
|
|
||||||
## 1.2.3
|
## 1.2.3
|
||||||
|
|
||||||
- Allow `toggle:<attribute>` to be used without a state
|
- Allow `toggle:<attribute>` to be used without a state
|
||||||
|
|
||||||
## 1.2.4
|
## 1.2.4
|
||||||
|
|
||||||
- On `subscribe:children`, scroll new elements into view
|
- On `subscribe:children`, scroll new elements into view
|
||||||
|
|
||||||
|
## 1.2.5
|
||||||
|
|
||||||
|
- Instead of using `scrollIntoView()`, `subscribe:children` now scrolls to the bottom
|
||||||
+3
-6
@@ -205,19 +205,16 @@ export function createElement(
|
|||||||
try {
|
try {
|
||||||
const [listState, toElement] = value as [
|
const [listState, toElement] = value as [
|
||||||
listState: ListState<any>,
|
listState: ListState<any>,
|
||||||
(
|
ListItemConverter<any>
|
||||||
item: any,
|
|
||||||
listState: ListState<any>
|
|
||||||
) => HTMLElement
|
|
||||||
];
|
];
|
||||||
|
|
||||||
listState.handleAddition((newItem) => {
|
listState.handleAddition((newItem) => {
|
||||||
const child = toElement(newItem, listState);
|
const child = toElement(newItem);
|
||||||
listState.handleRemoval(newItem, () =>
|
listState.handleRemoval(newItem, () =>
|
||||||
child.remove()
|
child.remove()
|
||||||
);
|
);
|
||||||
element.append(child);
|
element.append(child);
|
||||||
child.scrollIntoView();
|
element.scrollTop = element.scrollHeight;
|
||||||
});
|
});
|
||||||
} catch {
|
} catch {
|
||||||
throw `error: cannot process subscribe:children directive because ListItemConverter is not defined. Usage: "subscribe:children={[list, converter]}"; you can find a more detailed example in the documentation`;
|
throw `error: cannot process subscribe:children directive because ListItemConverter is not defined. Usage: "subscribe:children={[list, converter]}"; you can find a more detailed example in the documentation`;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bloatless-react",
|
"name": "bloatless-react",
|
||||||
"version": "1.2.4",
|
"version": "1.2.5-beta1",
|
||||||
"description": "very minimal and flexible react alternative",
|
"description": "very minimal and flexible react alternative",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
+19
-2
@@ -35,10 +35,18 @@ UDN.unsubscribe("my-channel");
|
|||||||
|
|
||||||
```TypeScript
|
```TypeScript
|
||||||
export interface Message {
|
export interface Message {
|
||||||
|
// connecting to server
|
||||||
|
requestingServerConnection?: boolean;
|
||||||
|
|
||||||
|
// mailbox
|
||||||
|
requestingMailboxSetup?: boolean;
|
||||||
|
assignedMailboxId?: string; // sent by server
|
||||||
|
requestedMailbox?: string;
|
||||||
|
|
||||||
// subscribing to channel
|
// subscribing to channel
|
||||||
subscribeChannel?: string;
|
subscribeChannel?: string;
|
||||||
unsubscribeChannel?: string;
|
unsubscribeChannel?: string;
|
||||||
subscribed?: boolean; // sent by the server to confirm subscription
|
subscribed?: boolean; // sent by server to confirm subscription
|
||||||
|
|
||||||
//sending message
|
//sending message
|
||||||
messageChannel?: string;
|
messageChannel?: string;
|
||||||
@@ -46,7 +54,7 @@ export interface Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class UDNFrontend {
|
export default class UDNFrontend {
|
||||||
private ws: WebSocket | undefined;
|
ws: WebSocket | undefined;
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
private connectionHandler = () => {};
|
private connectionHandler = () => {};
|
||||||
@@ -60,6 +68,7 @@ export default class UDNFrontend {
|
|||||||
|
|
||||||
// methods
|
// methods
|
||||||
connect(address: string): void;
|
connect(address: string): void;
|
||||||
|
disconnect(address: string): void;
|
||||||
sendMessage(channel: string, body: string): boolean; // true if message is sent
|
sendMessage(channel: string, body: string): boolean; // true if message is sent
|
||||||
subscribe(channel: string): boolean; // true if request is sent, NOT inherently when subscribed
|
subscribe(channel: string): boolean; // true if request is sent, NOT inherently when subscribed
|
||||||
unsubscribe(channel: string): boolean; // true if request is sent, NOT inherently when unsubscribed
|
unsubscribe(channel: string): boolean; // true if request is sent, NOT inherently when unsubscribed
|
||||||
@@ -75,3 +84,11 @@ export default class UDNFrontend {
|
|||||||
## 1.0.2
|
## 1.0.2
|
||||||
|
|
||||||
- minor fixes
|
- minor fixes
|
||||||
|
|
||||||
|
## 1.0.3
|
||||||
|
|
||||||
|
- add `disconnect()` method
|
||||||
|
|
||||||
|
## 1.0.4
|
||||||
|
|
||||||
|
- make ws public
|
||||||
+40
-3
@@ -1,8 +1,16 @@
|
|||||||
export interface Message {
|
export interface Message {
|
||||||
|
// connecting to server
|
||||||
|
requestingServerConnection?: boolean;
|
||||||
|
|
||||||
|
// mailbox
|
||||||
|
requestingMailboxSetup?: boolean;
|
||||||
|
assignedMailboxId?: string; // sent by server
|
||||||
|
requestedMailbox?: string;
|
||||||
|
|
||||||
// subscribing to channel
|
// subscribing to channel
|
||||||
subscribeChannel?: string;
|
subscribeChannel?: string;
|
||||||
unsubscribeChannel?: string;
|
unsubscribeChannel?: string;
|
||||||
subscribed?: boolean; // sent by the server to confirm subscription
|
subscribed?: boolean; // sent by server to confirm subscription
|
||||||
|
|
||||||
//sending message
|
//sending message
|
||||||
messageChannel?: string;
|
messageChannel?: string;
|
||||||
@@ -10,12 +18,13 @@ export interface Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class UDNFrontend {
|
export default class UDNFrontend {
|
||||||
private ws: WebSocket | undefined;
|
ws: WebSocket | undefined;
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
private connectionHandler = () => {};
|
private connectionHandler = () => {};
|
||||||
private disconnectionHandler = () => {};
|
private disconnectionHandler = () => {};
|
||||||
private messageHandler = (data: Message) => {};
|
private messageHandler = (data: Message) => {};
|
||||||
|
private mailboxHandler = (mailboxId: string) => {};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
set onconnect(handler: () => void) {
|
set onconnect(handler: () => void) {
|
||||||
@@ -27,9 +36,12 @@ export default class UDNFrontend {
|
|||||||
set onmessage(handler: (data: Message) => void) {
|
set onmessage(handler: (data: Message) => void) {
|
||||||
this.messageHandler = handler;
|
this.messageHandler = handler;
|
||||||
}
|
}
|
||||||
|
set onmailbox(handler: (mailboxId: string) => void) {
|
||||||
|
this.mailboxHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
// utility methods
|
// utility methods
|
||||||
private send(messageObject: Object): boolean {
|
private send(messageObject: Message): boolean {
|
||||||
if (this.ws == undefined) return false;
|
if (this.ws == undefined) return false;
|
||||||
|
|
||||||
const messageString = JSON.stringify(messageObject);
|
const messageString = JSON.stringify(messageObject);
|
||||||
@@ -39,16 +51,27 @@ export default class UDNFrontend {
|
|||||||
|
|
||||||
// public methods
|
// public methods
|
||||||
connect(address: string): void {
|
connect(address: string): void {
|
||||||
|
this.disconnect();
|
||||||
|
|
||||||
this.ws = new WebSocket(address);
|
this.ws = new WebSocket(address);
|
||||||
this.ws.addEventListener("open", this.connectionHandler);
|
this.ws.addEventListener("open", this.connectionHandler);
|
||||||
this.ws.addEventListener("close", this.disconnectionHandler);
|
this.ws.addEventListener("close", this.disconnectionHandler);
|
||||||
this.ws.addEventListener("message", (message) => {
|
this.ws.addEventListener("message", (message) => {
|
||||||
const dataString = message.data.toString();
|
const dataString = message.data.toString();
|
||||||
const data = JSON.parse(dataString);
|
const data = JSON.parse(dataString);
|
||||||
|
|
||||||
|
if (data.assignedMailboxId) {
|
||||||
|
return this.mailboxHandler(data.assignedMailboxId);
|
||||||
|
} else {
|
||||||
this.messageHandler(data);
|
this.messageHandler(data);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnect(): void {
|
||||||
|
this.ws?.close();
|
||||||
|
}
|
||||||
|
|
||||||
sendMessage(channel: string, body: string): boolean {
|
sendMessage(channel: string, body: string): boolean {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
messageChannel: channel,
|
messageChannel: channel,
|
||||||
@@ -70,4 +93,18 @@ export default class UDNFrontend {
|
|||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestMailbox(): boolean {
|
||||||
|
const messageObject = {
|
||||||
|
requestingMailboxSetup: true,
|
||||||
|
};
|
||||||
|
return this.send(messageObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
accessMailbox(mailboxId: string): boolean {
|
||||||
|
const messageObject = {
|
||||||
|
requestedMailbox: mailboxId,
|
||||||
|
};
|
||||||
|
return this.send(messageObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "udn-frontend",
|
"name": "udn-frontend",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4-beta2",
|
||||||
"description": "TypeScript library for UDN apps",
|
"description": "TypeScript library for UDN apps",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bloatless-react": "^1.2.4",
|
"bloatless-react": "1.2.5-beta1",
|
||||||
"esbuild": "latest",
|
"esbuild": "latest",
|
||||||
"udn-frontend": "^1.0.2"
|
"udn-frontend": "1.0.4-beta2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild src/index.tsx --bundle --outdir=dist"
|
"build": "esbuild src/index.tsx --bundle --outdir=dist"
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import * as React from "bloatless-react";
|
|||||||
import {
|
import {
|
||||||
isMessageEmpty,
|
isMessageEmpty,
|
||||||
lastReceivedMessage,
|
lastReceivedMessage,
|
||||||
|
mailboxId,
|
||||||
newMessageBody,
|
newMessageBody,
|
||||||
newMessageChannel,
|
newMessageChannel,
|
||||||
|
requestMailbox,
|
||||||
sendMessage,
|
sendMessage,
|
||||||
subscribe,
|
subscribe,
|
||||||
subscriptionChannel,
|
subscriptionChannel,
|
||||||
@@ -28,6 +30,22 @@ export function MainScreen() {
|
|||||||
|
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
|
<div class="tile width-input">
|
||||||
|
<div>
|
||||||
|
<b>{getText("mailbox")}</b>
|
||||||
|
<p class="secondary" subscribe:innerText={mailboxId}></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-row width-input justify-end">
|
||||||
|
<button class="primary width-100" on:click={requestMailbox}>
|
||||||
|
{getText("requestMailbox")}
|
||||||
|
<span class="icon">inbox</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr></hr>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<div>
|
<div>
|
||||||
<span>{getText("subscribeToChannel")}</span>
|
<span>{getText("subscribeToChannel")}</span>
|
||||||
|
|||||||
+13
-1
@@ -4,7 +4,7 @@ import UDNFrontend from "udn-frontend";
|
|||||||
import { getText } from "./translations";
|
import { getText } from "./translations";
|
||||||
|
|
||||||
export class Message implements React.Identifiable {
|
export class Message implements React.Identifiable {
|
||||||
uuid = new React.UUID();
|
id = React.UUID();
|
||||||
|
|
||||||
constructor(public channel: string, public body: string) {}
|
constructor(public channel: string, public body: string) {}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,9 @@ const UDN = new UDNFrontend();
|
|||||||
UDN.onconnect = () => {
|
UDN.onconnect = () => {
|
||||||
isDisconnected.value = false;
|
isDisconnected.value = false;
|
||||||
updateStats();
|
updateStats();
|
||||||
|
if (mailboxId.value != "") {
|
||||||
|
UDN.accessMailbox(mailboxId.value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
UDN.onmessage = (data) => {
|
UDN.onmessage = (data) => {
|
||||||
@@ -27,6 +30,10 @@ UDN.onmessage = (data) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UDN.onmailbox = (id) => {
|
||||||
|
mailboxId.value = id;
|
||||||
|
};
|
||||||
|
|
||||||
UDN.ondisconnect = () => {
|
UDN.ondisconnect = () => {
|
||||||
isDisconnected.value = true;
|
isDisconnected.value = true;
|
||||||
setTimeout(connect, 2000);
|
setTimeout(connect, 2000);
|
||||||
@@ -40,6 +47,7 @@ connect();
|
|||||||
// STATE
|
// STATE
|
||||||
// connection
|
// connection
|
||||||
export const isDisconnected = new React.State(true);
|
export const isDisconnected = new React.State(true);
|
||||||
|
export const mailboxId = React.restoreState("mailbox-id", "");
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
export const messages = new React.ListState<Message>();
|
export const messages = new React.ListState<Message>();
|
||||||
@@ -93,3 +101,7 @@ export function sendMessage() {
|
|||||||
UDN.sendMessage(newMessageChannel.value, newMessageBody.value);
|
UDN.sendMessage(newMessageChannel.value, newMessageBody.value);
|
||||||
newMessageBody.value = "";
|
newMessageBody.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function requestMailbox() {
|
||||||
|
UDN.requestMailbox();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
// STATIC
|
// STATIC
|
||||||
export const staticTextEnglish = {
|
export const staticTextEnglish = {
|
||||||
|
mailbox: "Mailbox",
|
||||||
|
requestMailbox: "Request Mailbox",
|
||||||
channel: "Channel",
|
channel: "Channel",
|
||||||
channel_placeholder: "my-channel",
|
channel_placeholder: "my-channel",
|
||||||
disconnected: "Server disconnected",
|
disconnected: "Server disconnected",
|
||||||
@@ -23,6 +25,8 @@ export const staticTextEnglish = {
|
|||||||
export const translations: { [key: string]: typeof staticTextEnglish } = {
|
export const translations: { [key: string]: typeof staticTextEnglish } = {
|
||||||
en: staticTextEnglish,
|
en: staticTextEnglish,
|
||||||
es: {
|
es: {
|
||||||
|
mailbox: "Buzón",
|
||||||
|
requestMailbox: "Solicitar buzón",
|
||||||
channel: "Canal",
|
channel: "Canal",
|
||||||
channel_placeholder: "mi-canal",
|
channel_placeholder: "mi-canal",
|
||||||
disconnected: "Sin coneción",
|
disconnected: "Sin coneción",
|
||||||
@@ -43,6 +47,8 @@ export const translations: { [key: string]: typeof staticTextEnglish } = {
|
|||||||
unsubscribe: "Cancelar",
|
unsubscribe: "Cancelar",
|
||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
|
mailbox: "Briefkasten",
|
||||||
|
requestMailbox: "Briefkasten beantragen",
|
||||||
channel: "Kanal",
|
channel: "Kanal",
|
||||||
channel_placeholder: "mein-kanal",
|
channel_placeholder: "mein-kanal",
|
||||||
disconnected: "Verbindung getrennt",
|
disconnected: "Verbindung getrennt",
|
||||||
|
|||||||
+59
-9
@@ -1,3 +1,9 @@
|
|||||||
|
import {
|
||||||
|
WebSocketMessage,
|
||||||
|
sendWebSocketMessage,
|
||||||
|
subscriptionMap,
|
||||||
|
} from "./websocket-handler";
|
||||||
|
|
||||||
import Crypto from "crypto";
|
import Crypto from "crypto";
|
||||||
import { WS } from "./index";
|
import { WS } from "./index";
|
||||||
|
|
||||||
@@ -6,19 +12,38 @@ export interface Subscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Mailbox implements Subscriber {
|
export class Mailbox implements Subscriber {
|
||||||
// basic
|
// basic data
|
||||||
id = Crypto.randomUUID();
|
id = Crypto.randomUUID();
|
||||||
dateLastChecked = new Date();
|
dateLastChecked = new Date();
|
||||||
messages = new Set<string>();
|
|
||||||
|
|
||||||
get expiryDate() {
|
get expiryDate() {
|
||||||
const expiryDate = new Date(this.dateLastChecked);
|
const expiryDate = new Date(this.dateLastChecked);
|
||||||
expiryDate.setDate(expiryDate.getDate() + 7);
|
TODO expiryDate.setDate(expiryDate.getDate() + 7);
|
||||||
return expiryDate;
|
return expiryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init
|
||||||
|
constructor(ws: WS) {
|
||||||
|
this.ws = ws;
|
||||||
|
this.sendId();
|
||||||
|
}
|
||||||
|
|
||||||
|
sendId(): void {
|
||||||
|
if (!this.ws) return;
|
||||||
|
|
||||||
|
sendWebSocketMessage(
|
||||||
|
{
|
||||||
|
assignedMailboxId: this.id,
|
||||||
|
},
|
||||||
|
this.ws
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// storage
|
||||||
|
messages = new Set<string>();
|
||||||
|
|
||||||
// websocket
|
// websocket
|
||||||
_ws: WS | undefined;
|
private _ws: WS | undefined;
|
||||||
|
|
||||||
get ws(): WS | undefined {
|
get ws(): WS | undefined {
|
||||||
return this._ws;
|
return this._ws;
|
||||||
@@ -26,19 +51,36 @@ export class Mailbox implements Subscriber {
|
|||||||
|
|
||||||
set ws(ws: WS) {
|
set ws(ws: WS) {
|
||||||
this._ws = ws;
|
this._ws = ws;
|
||||||
|
this.dateLastChecked = new Date();
|
||||||
|
|
||||||
this.sendUnreadMessages();
|
this.sendUnreadMessages();
|
||||||
|
|
||||||
|
const channels = subscriptionMap.getChannelList(ws);
|
||||||
|
channels?.forEach((channel) => this.subscribe(channel));
|
||||||
|
|
||||||
|
subscriptionMap.deleteSubscriber(ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
// subscribing
|
||||||
|
subscribe(channelName: string): void {
|
||||||
|
subscriptionMap.set(this, channelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe(channelName: string): void {
|
||||||
|
subscriptionMap.delete(this, channelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sending
|
// sending
|
||||||
send(message) {
|
send(message: string): void {
|
||||||
if (this._ws) {
|
if (this._ws?.readyState == 1) {
|
||||||
this._ws.send(message);
|
this._ws.send(message);
|
||||||
} else {
|
} else {
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendUnreadMessages() {
|
sendUnreadMessages(): void {
|
||||||
|
console.log(this.messages);
|
||||||
this.messages.forEach((message) => {
|
this.messages.forEach((message) => {
|
||||||
if (!this._ws) return;
|
if (!this._ws) return;
|
||||||
|
|
||||||
@@ -96,11 +138,19 @@ export class SubscriptionMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteSubscriber(subscriber: Subscriber): void {
|
||||||
|
this.getChannelList(subscriber)?.forEach((channel) => {
|
||||||
|
this.delete(subscriber, channel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
forwardMessage(channels: string[], messageString: string): void {
|
forwardMessage(channels: string[], messageObject: WebSocketMessage): void {
|
||||||
channels.forEach((channel) => {
|
channels.forEach((channel) => {
|
||||||
const subscribers = this.getClientList(channel);
|
const subscribers = this.getClientList(channel);
|
||||||
subscribers?.forEach((subscriber) => subscriber.send(messageString));
|
subscribers?.forEach((subscriber) => {
|
||||||
|
sendWebSocketMessage(messageObject, subscriber);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-2
@@ -1,9 +1,14 @@
|
|||||||
import { PACKAGE_FILE, STATIC_DIR } from ".";
|
import { Mailbox, Subscriber } from "./subscriptionHandler";
|
||||||
|
import { PACKAGE_FILE, STATIC_DIR, WS } from ".";
|
||||||
|
import {
|
||||||
|
WebSocketMessage,
|
||||||
|
mailboxIdsPerClient,
|
||||||
|
mailboxes,
|
||||||
|
} from "./websocket-handler";
|
||||||
|
|
||||||
import Colors from "colors";
|
import Colors from "colors";
|
||||||
import Fs from "fs/promises";
|
import Fs from "fs/promises";
|
||||||
import Path from "path";
|
import Path from "path";
|
||||||
import { WebSocketMessage } from "./websocket-handler";
|
|
||||||
|
|
||||||
// CONFIG
|
// CONFIG
|
||||||
const STAT_INDENT = 25;
|
const STAT_INDENT = 25;
|
||||||
@@ -65,3 +70,14 @@ export function stringifyMessage(messageObject: WebSocketMessage): string {
|
|||||||
export function parseMessage(messageString: string): Object {
|
export function parseMessage(messageString: string): Object {
|
||||||
return JSON.parse(messageString);
|
return JSON.parse(messageString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SUBSCRIBERS
|
||||||
|
export function getMailboxIfExists(ws: WS): Mailbox | undefined {
|
||||||
|
const id = mailboxIdsPerClient.get(ws);
|
||||||
|
if (!id) return;
|
||||||
|
return mailboxes.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMostAppropriateSubscriber(ws: WS): Subscriber {
|
||||||
|
return getMailboxIfExists(ws) ?? ws;
|
||||||
|
}
|
||||||
|
|||||||
+57
-23
@@ -1,6 +1,8 @@
|
|||||||
import { Subscriber, SubscriptionMap } from "./subscriptionHandler";
|
import { Mailbox, Subscriber, SubscriptionMap } from "./subscriptionHandler";
|
||||||
import {
|
import {
|
||||||
doIfIsString,
|
doIfIsString,
|
||||||
|
getMailboxIfExists,
|
||||||
|
getMostAppropriateSubscriber,
|
||||||
parseMessage,
|
parseMessage,
|
||||||
stringifyMessage,
|
stringifyMessage,
|
||||||
writeError,
|
writeError,
|
||||||
@@ -39,6 +41,8 @@ const knownMessageIds = new Set<string>();
|
|||||||
export const subscriptionMap = new SubscriptionMap();
|
export const subscriptionMap = new SubscriptionMap();
|
||||||
|
|
||||||
export const clientsConnected = new Set<WS>();
|
export const clientsConnected = new Set<WS>();
|
||||||
|
export const mailboxes = new Map<string, Mailbox>();
|
||||||
|
export const mailboxIdsPerClient = new Map<WS, string>();
|
||||||
|
|
||||||
export const serversConnectedAsClient = new Set<WS>();
|
export const serversConnectedAsClient = new Set<WS>();
|
||||||
export const serversConnected = new Set<WebSocket>();
|
export const serversConnected = new Set<WebSocket>();
|
||||||
@@ -55,11 +59,7 @@ export function trackConnection(ws: WS) {
|
|||||||
export function forgetConnection(ws: WS): void {
|
export function forgetConnection(ws: WS): void {
|
||||||
clientsConnected.delete(ws);
|
clientsConnected.delete(ws);
|
||||||
serversConnectedAsClient.delete(ws);
|
serversConnectedAsClient.delete(ws);
|
||||||
|
subscriptionMap.deleteSubscriber(ws);
|
||||||
const channels = subscriptionMap.getChannelList(ws);
|
|
||||||
channels?.forEach((channel) => {
|
|
||||||
subscriptionMap.delete(ws, channel);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trackSubscription(
|
export function trackSubscription(
|
||||||
@@ -78,6 +78,17 @@ export function forgetSubscription(
|
|||||||
confirmSubscription(subscriber, channel);
|
confirmSubscription(subscriber, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AUDIT
|
||||||
|
export function getWebSocketStats(): [string, number][] {
|
||||||
|
return [
|
||||||
|
["channels", subscriptionMap.subscribersPerChannel.size],
|
||||||
|
["clients connected", clientsConnected.size],
|
||||||
|
["mailboxes", mailboxes.size],
|
||||||
|
["servers connected", getServerCount()],
|
||||||
|
["servers disconnected", serversDisconnected.size],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// OTHER SERVERS
|
// OTHER SERVERS
|
||||||
export function connectServers(config: typeof defaultConfig): void {
|
export function connectServers(config: typeof defaultConfig): void {
|
||||||
config.connectedServers.forEach((serverAddress) => {
|
config.connectedServers.forEach((serverAddress) => {
|
||||||
@@ -138,16 +149,6 @@ export function subscribeChannel(server: WS, channel: string): void {
|
|||||||
server.send(messageString);
|
server.send(messageString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUDIT
|
|
||||||
export function getWebSocketStats(): [string, number][] {
|
|
||||||
return [
|
|
||||||
["channels", subscriptionMap.subscribersPerChannel.size],
|
|
||||||
["clients connected", clientsConnected.size],
|
|
||||||
["servers connected", getServerCount()],
|
|
||||||
["servers disconnected", serversDisconnected.size],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// PROCESS MESSAGE
|
// PROCESS MESSAGE
|
||||||
export function processMessage(
|
export function processMessage(
|
||||||
ws: WS,
|
ws: WS,
|
||||||
@@ -169,10 +170,10 @@ export function processMessage(
|
|||||||
|
|
||||||
// SUBSCRIPTIONS
|
// SUBSCRIPTIONS
|
||||||
doIfIsString(messageObject.subscribeChannel, (subscribeChannel) => {
|
doIfIsString(messageObject.subscribeChannel, (subscribeChannel) => {
|
||||||
trackSubscription(ws, subscribeChannel);
|
trackSubscription(getMostAppropriateSubscriber(ws), subscribeChannel);
|
||||||
});
|
});
|
||||||
doIfIsString(messageObject.unsubscribeChannel, (unsubscribeChannel) => {
|
doIfIsString(messageObject.unsubscribeChannel, (unsubscribeChannel) => {
|
||||||
forgetSubscription(ws, unsubscribeChannel);
|
forgetSubscription(getMostAppropriateSubscriber(ws), unsubscribeChannel);
|
||||||
});
|
});
|
||||||
|
|
||||||
// MESSAGE
|
// MESSAGE
|
||||||
@@ -181,6 +182,17 @@ export function processMessage(
|
|||||||
sendMessage(messageChannel, messageObject.messageBody, messageObject.uuid!);
|
sendMessage(messageChannel, messageObject.messageBody, messageObject.uuid!);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// MAILBOX
|
||||||
|
if (messageObject.requestingMailboxSetup == true) {
|
||||||
|
const mailbox = new Mailbox(ws);
|
||||||
|
mailboxes.set(mailbox.id, mailbox);
|
||||||
|
}
|
||||||
|
doIfIsString(messageObject.requestedMailbox, (requestedMailbox) => {
|
||||||
|
const mailbox = mailboxes.get(requestedMailbox);
|
||||||
|
if (!mailbox) return;
|
||||||
|
mailbox.ws = ws;
|
||||||
|
});
|
||||||
|
|
||||||
// OTHER SERVER
|
// OTHER SERVER
|
||||||
if (messageObject.requestingServerConnection == true) {
|
if (messageObject.requestingServerConnection == true) {
|
||||||
clientsConnected.delete(ws);
|
clientsConnected.delete(ws);
|
||||||
@@ -189,18 +201,40 @@ export function processMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MAILBOX
|
||||||
|
export function removeExpiredMailboxes() {
|
||||||
|
const today = new Date();
|
||||||
|
mailboxes.forEach((mailbox) => {
|
||||||
|
if (mailbox.expiryDate > today) return;
|
||||||
|
removeMailbox(mailbox);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeMailbox(mailbox: Mailbox) {
|
||||||
|
subscriptionMap.deleteSubscriber(mailbox);
|
||||||
|
mailboxes.delete(mailbox.id);
|
||||||
|
}
|
||||||
|
|
||||||
// MESSAGING
|
// MESSAGING
|
||||||
|
export function sendWebSocketMessage(
|
||||||
|
messageObject: WebSocketMessage,
|
||||||
|
destination: Subscriber
|
||||||
|
): void {
|
||||||
|
const messageString = JSON.stringify(messageObject);
|
||||||
|
destination.send(messageString);
|
||||||
|
}
|
||||||
|
|
||||||
export function sendMessage(
|
export function sendMessage(
|
||||||
messageChannel: string,
|
messageChannel: string,
|
||||||
messageBody: string,
|
messageBody: string,
|
||||||
uuid: string
|
uuid: string
|
||||||
): void {
|
): void {
|
||||||
const channels = messageChannel.split("/");
|
const channels = messageChannel.split("/");
|
||||||
|
subscriptionMap.forwardMessage(channels, {
|
||||||
const messageObject = { uuid, messageChannel, messageBody };
|
uuid,
|
||||||
const messageString = stringifyMessage(messageObject);
|
messageChannel,
|
||||||
|
messageBody,
|
||||||
subscriptionMap.forwardMessage(channels, messageString);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestServerConnection(ws: WS): void {
|
function requestServerConnection(ws: WS): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user