Successfully receive websocket data on frontend
This commit is contained in:
parent
fb87fc0bcf
commit
19c42a8049
|
@ -1,5 +1,6 @@
|
||||||
import * as pty from "node-pty";
|
import * as pty from "node-pty";
|
||||||
import { IPty } from "node-pty";
|
import { IPty } from "node-pty";
|
||||||
|
import * as WebSocket from "ws";
|
||||||
|
|
||||||
import { LangConfig, langs } from "./langs";
|
import { LangConfig, langs } from "./langs";
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ export class Session {
|
||||||
term: IPty;
|
term: IPty;
|
||||||
ws: WebSocket;
|
ws: WebSocket;
|
||||||
|
|
||||||
constructor(ws, lang) {
|
constructor(ws: WebSocket, lang: string) {
|
||||||
this.ws = ws;
|
this.ws = ws;
|
||||||
this.config = langs[lang];
|
this.config = langs[lang];
|
||||||
this.term = null;
|
this.term = null;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as appRoot from "app-root-path";
|
import * as appRoot from "app-root-path";
|
||||||
import * as express from "express";
|
import * as express from "express";
|
||||||
|
import { Request } from "express";
|
||||||
import * as ws from "express-ws";
|
import * as ws from "express-ws";
|
||||||
import * as sslRedirect from "heroku-ssl-redirect";
|
import * as sslRedirect from "heroku-ssl-redirect";
|
||||||
|
|
||||||
|
@ -10,6 +11,14 @@ const app = ws(express()).app;
|
||||||
const host = process.env.HOST || "localhost";
|
const host = process.env.HOST || "localhost";
|
||||||
const port = parseInt(process.env.PORT) || 6119;
|
const port = parseInt(process.env.PORT) || 6119;
|
||||||
|
|
||||||
|
app.set("query parser", (qs: string) => new URLSearchParams(qs));
|
||||||
|
|
||||||
|
function getQueryParams(req: Request): URLSearchParams {
|
||||||
|
// This is safe because we set the query parser for Express to
|
||||||
|
// return URLSearchParams objects.
|
||||||
|
return (req.query as unknown) as URLSearchParams;
|
||||||
|
}
|
||||||
|
|
||||||
app.use(sslRedirect());
|
app.use(sslRedirect());
|
||||||
app.get("/", (_, res) => {
|
app.get("/", (_, res) => {
|
||||||
res.sendFile(appRoot.path + "/frontend/pages/index.html");
|
res.sendFile(appRoot.path + "/frontend/pages/index.html");
|
||||||
|
@ -23,19 +32,24 @@ app.get("/:lang", (req, res) => {
|
||||||
});
|
});
|
||||||
app.use("/css", express.static(appRoot.path + "/frontend/styles"));
|
app.use("/css", express.static(appRoot.path + "/frontend/styles"));
|
||||||
app.use("/js", express.static(appRoot.path + "/frontend/out"));
|
app.use("/js", express.static(appRoot.path + "/frontend/out"));
|
||||||
app.use("/api/v1/ws", (req, res, next) => {
|
|
||||||
if (!req.query.lang) {
|
|
||||||
res.status(400);
|
|
||||||
res.send("No language specified");
|
|
||||||
} else if (!langs[req.query.lang as string]) {
|
|
||||||
res.status(400);
|
|
||||||
res.send(`No such language: ${req.query.lang}`);
|
|
||||||
} else {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
app.ws("/api/v1/ws", (ws, req) => {
|
app.ws("/api/v1/ws", (ws, req) => {
|
||||||
new api.Session(ws, req.query.lang);
|
const lang = getQueryParams(req).get("lang");
|
||||||
|
if (!lang) {
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({ event: "error", errorMessage: "No language specified" })
|
||||||
|
);
|
||||||
|
ws.close();
|
||||||
|
} else if (!langs[lang]) {
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
event: "error",
|
||||||
|
errorMessage: `No such language: ${lang}`,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
ws.close();
|
||||||
|
} else {
|
||||||
|
new api.Session(ws, getQueryParams(req).get("lang"));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(port, host, () =>
|
app.listen(port, host, () =>
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { FitAddon } from "xterm-addon-fit";
|
||||||
|
|
||||||
import "xterm/css/xterm.css";
|
import "xterm/css/xterm.css";
|
||||||
|
|
||||||
|
const lang = document.location.pathname.slice(1);
|
||||||
|
|
||||||
const term = new Terminal();
|
const term = new Terminal();
|
||||||
const fitAddon = new FitAddon();
|
const fitAddon = new FitAddon();
|
||||||
term.loadAddon(fitAddon);
|
term.loadAddon(fitAddon);
|
||||||
|
@ -14,11 +16,11 @@ window.addEventListener("resize", () => fitAddon.fit());
|
||||||
const socket = new WebSocket(
|
const socket = new WebSocket(
|
||||||
(document.location.protocol === "http:" ? "ws://" : "wss://") +
|
(document.location.protocol === "http:" ? "ws://" : "wss://") +
|
||||||
document.location.host +
|
document.location.host +
|
||||||
"/api/v1/ws"
|
`/api/v1/ws?lang=${lang}`
|
||||||
);
|
);
|
||||||
|
|
||||||
socket.onopen = () => console.log("Successfully connected to server");
|
socket.onopen = () => console.log("Successfully connected to server");
|
||||||
socket.onmessage = (event) => console.log(event);
|
socket.onmessage = (event) => console.log(JSON.parse(event.data));
|
||||||
socket.onclose = (event) => {
|
socket.onclose = (event) => {
|
||||||
if (event.wasClean) {
|
if (event.wasClean) {
|
||||||
console.log("Connection closed cleanly");
|
console.log("Connection closed cleanly");
|
||||||
|
|
|
@ -10,6 +10,17 @@ fi
|
||||||
|
|
||||||
uid="$1"
|
uid="$1"
|
||||||
|
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y curl gnupg
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||||
|
|
||||||
|
tee -a /etc/apt/sources.list.d/yarn.list >/dev/null <<"EOF"
|
||||||
|
deb https://dl.yarnpkg.com/debian/ stable main
|
||||||
|
EOF
|
||||||
|
|
||||||
packages="
|
packages="
|
||||||
|
|
||||||
# Handy utilities
|
# Handy utilities
|
||||||
|
@ -20,6 +31,7 @@ git
|
||||||
make
|
make
|
||||||
nano
|
nano
|
||||||
sudo
|
sudo
|
||||||
|
tmux
|
||||||
vim
|
vim
|
||||||
wget
|
wget
|
||||||
|
|
||||||
|
@ -32,7 +44,7 @@ ghc
|
||||||
|
|
||||||
# Node.js
|
# Node.js
|
||||||
nodejs
|
nodejs
|
||||||
npm
|
yarn
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
python3
|
python3
|
||||||
|
|
Loading…
Reference in New Issue