Handle typing messages
This commit is contained in:
parent
6c5d3bbe21
commit
1a3b994489
4 changed files with 60 additions and 16 deletions
2
lib
2
lib
|
@ -1 +1 @@
|
||||||
Subproject commit 61c9d61229a18f5b484a7927bc343650024efc96
|
Subproject commit a957a29498d6b9c3b121f8e27e43ad73d9342075
|
|
@ -25,10 +25,10 @@
|
||||||
"@rollup/plugin-commonjs": "^21.0.1",
|
"@rollup/plugin-commonjs": "^21.0.1",
|
||||||
"@rollup/plugin-node-resolve": "^13.1.3",
|
"@rollup/plugin-node-resolve": "^13.1.3",
|
||||||
"@types/ws": "^8.2.2",
|
"@types/ws": "^8.2.2",
|
||||||
"rollup": "^2.63.0",
|
"rollup": "^2.64.0",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"rollup-plugin-typescript2": "^0.31.1",
|
"rollup-plugin-typescript2": "^0.31.1",
|
||||||
"typescript": "^4.5.4",
|
"typescript": "^4.5.4",
|
||||||
"ws": "^8.4.1"
|
"ws": "^8.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,19 @@ import type {
|
||||||
AckMessage,
|
AckMessage,
|
||||||
IdResponseMessage,
|
IdResponseMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
|
TypingMessage,
|
||||||
} from "./lib/ServerMessage";
|
} from "./lib/ServerMessage";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isServerMessage,
|
isServerMessage,
|
||||||
isTextMessage,
|
isTextMessage,
|
||||||
|
isTypingMessage,
|
||||||
MessageType,
|
MessageType,
|
||||||
} from "./lib/ServerMessage";
|
} from "./lib/ServerMessage";
|
||||||
|
|
||||||
const port = 8085;
|
const port = 8085;
|
||||||
const timeout = 15000;
|
const timeout = 15000;
|
||||||
|
const typingTimeout = 2000;
|
||||||
|
|
||||||
const httpsServer = https.createServer({
|
const httpsServer = https.createServer({
|
||||||
key: fs.readFileSync("./key.pem"),
|
key: fs.readFileSync("./key.pem"),
|
||||||
|
@ -25,6 +28,10 @@ const httpsServer = https.createServer({
|
||||||
});
|
});
|
||||||
const webSocketServer = new WebSocketServer({ server: httpsServer });
|
const webSocketServer = new WebSocketServer({ server: httpsServer });
|
||||||
|
|
||||||
|
/* If not using SSL/TLS
|
||||||
|
const webSocketServer = new WebSocketServer({ port });
|
||||||
|
*/
|
||||||
|
|
||||||
console.log("listening on port: " + port);
|
console.log("listening on port: " + port);
|
||||||
|
|
||||||
async function handleTextMessage(message: TextMessage, from: string) {
|
async function handleTextMessage(message: TextMessage, from: string) {
|
||||||
|
@ -39,12 +46,47 @@ async function handleTextMessage(message: TextMessage, from: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const activeConnections = new Set<string>();
|
||||||
|
const currentlyTyping = new Set<string>();
|
||||||
|
const currentlyTypingTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
|
||||||
|
|
||||||
|
async function handleTypingMessage(_message: TypingMessage, from: string) {
|
||||||
|
currentlyTyping.add(from);
|
||||||
|
|
||||||
|
if(currentlyTypingTimeouts.has(from)) {
|
||||||
|
clearTimeout(currentlyTypingTimeouts.get(from)!);
|
||||||
|
}
|
||||||
|
currentlyTypingTimeouts.set(from, setTimeout(() => {
|
||||||
|
currentlyTyping.delete(from);
|
||||||
|
currentlyTypingTimeouts.delete(from);
|
||||||
|
sendCurrentlyTypingMessage(from, true);
|
||||||
|
}, typingTimeout));
|
||||||
|
sendCurrentlyTypingMessage(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendCurrentlyTypingMessage(from?: string, stopped = false) {
|
||||||
|
for (const to of webSocketServer.clients) {
|
||||||
|
to.send(
|
||||||
|
JSON.stringify(
|
||||||
|
Object.assign({
|
||||||
|
type: MessageType.CURRENTLY_TYPING,
|
||||||
|
date: Date.now(),
|
||||||
|
}, {
|
||||||
|
currently: Array.from(currentlyTyping.values()),
|
||||||
|
}, from === undefined ? {
|
||||||
|
__ctx: "regular update",
|
||||||
|
} : {
|
||||||
|
__ctx: from + (stopped ? " stopped typing" : " started typing"),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleCloseConnection(id: string) {
|
async function handleCloseConnection(id: string) {
|
||||||
activeConnections.delete(id);
|
activeConnections.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeConnections = new Set<string>();
|
|
||||||
|
|
||||||
webSocketServer.on("connection", function connection(socket) {
|
webSocketServer.on("connection", function connection(socket) {
|
||||||
const close = (reason: string, code: number = 1000) => {
|
const close = (reason: string, code: number = 1000) => {
|
||||||
socket.send(
|
socket.send(
|
||||||
|
@ -71,6 +113,8 @@ webSocketServer.on("connection", function connection(socket) {
|
||||||
if (message.author === authorId) {
|
if (message.author === authorId) {
|
||||||
handleTextMessage(message, authorId);
|
handleTextMessage(message, authorId);
|
||||||
}
|
}
|
||||||
|
} else if (isTypingMessage(message)) {
|
||||||
|
handleTypingMessage(message, authorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTimeout(closeTimeout);
|
clearTimeout(closeTimeout);
|
||||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -84,9 +84,9 @@
|
||||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "17.0.8"
|
version "17.0.9"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.9.tgz#0b7f161afb5b1cc12518d29b2cdc7175d5490628"
|
||||||
integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==
|
integrity sha512-5dNBXu/FOER+EXnyah7rn8xlNrfMOQb/qXnw4NQgLkCygKBKhdmF/CA5oXVOKZLBEahw8s2WP9LxIcN/oDDRgQ==
|
||||||
|
|
||||||
"@types/resolve@1.17.1":
|
"@types/resolve@1.17.1":
|
||||||
version "1.17.1"
|
version "1.17.1"
|
||||||
|
@ -513,10 +513,10 @@ rollup-plugin-typescript2@^0.31.1:
|
||||||
resolve "1.20.0"
|
resolve "1.20.0"
|
||||||
tslib "2.2.0"
|
tslib "2.2.0"
|
||||||
|
|
||||||
rollup@^2.63.0:
|
rollup@^2.64.0:
|
||||||
version "2.63.0"
|
version "2.64.0"
|
||||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.63.0.tgz#fe2f7fec2133f3fab9e022b9ac245628d817c6bb"
|
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.64.0.tgz#f0f59774e21fbb56de438a37d06a2189632b207a"
|
||||||
integrity sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ==
|
integrity sha512-+c+lbw1lexBKSMb1yxGDVfJ+vchJH3qLbmavR+awDinTDA2C5Ug9u7lkOzj62SCu0PKUExsW36tpgW7Fmpn3yQ==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.2"
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
@ -635,10 +635,10 @@ wrappy@1:
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||||
|
|
||||||
ws@^8.4.1:
|
ws@^8.4.2:
|
||||||
version "8.4.1"
|
version "8.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.1.tgz#ce1a17e553d2b794e017fa94887808db5c67f614"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b"
|
||||||
integrity sha512-6eqQ4yN2y2xv8b+BgbkUzPPyfo/PDl3VOWb06ZE0jIFYwuHMsMQN6F7o84yxJYCblfCRAxzpU59We4Rr4w0Luw==
|
integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==
|
||||||
|
|
||||||
yocto-queue@^0.1.0:
|
yocto-queue@^0.1.0:
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
|
|
Reference in a new issue