Cleanup of server side state
This commit is contained in:
parent
a5979b2774
commit
fd7ccd596e
@ -104,7 +104,7 @@ const rules = (env) => {
|
||||
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
|
||||
loader: require.resolve("url-loader"),
|
||||
options: {
|
||||
limit: 10000,
|
||||
limit: (env === "prod") ? 10000 : 0,
|
||||
name: "static/media/[name].[hash:8].[ext]",
|
||||
},
|
||||
},
|
||||
|
@ -1,11 +1,20 @@
|
||||
import * as express from "express";
|
||||
|
||||
import * as schema from "@common/sprinklers/schema";
|
||||
import {serialize} from "serializr";
|
||||
import {state} from "../state";
|
||||
import logger from "./logger";
|
||||
import serveApp from "./serveApp";
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(logger);
|
||||
|
||||
app.get("/api/grinklers", (req, res) => {
|
||||
const j = serialize(schema.sprinklersDevice, state.device);
|
||||
res.send(j);
|
||||
});
|
||||
|
||||
serveApp(app);
|
||||
|
||||
export default app;
|
||||
|
@ -4,89 +4,22 @@ import "env";
|
||||
import "./configureLogger";
|
||||
|
||||
import log from "@common/logger";
|
||||
import * as mqtt from "@common/sprinklers/mqtt";
|
||||
import { Server } from "http";
|
||||
import {Server} from "http";
|
||||
import * as WebSocket from "ws";
|
||||
|
||||
import app from "./app";
|
||||
|
||||
const mqttClient = new mqtt.MqttApiClient("mqtt://localhost:1883");
|
||||
mqttClient.start();
|
||||
|
||||
import * as schema from "@common/sprinklers/schema";
|
||||
import * as requests from "@common/sprinklers/requests";
|
||||
import * as ws from "@common/sprinklers/websocketData";
|
||||
import { autorun } from "mobx";
|
||||
import { serialize } from "serializr";
|
||||
const device = mqttClient.getDevice("grinklers");
|
||||
|
||||
app.get("/api/grinklers", (req, res) => {
|
||||
const j = serialize(schema.sprinklersDevice, device);
|
||||
res.send(j);
|
||||
});
|
||||
|
||||
async function doDeviceCallRequest(requestData: ws.IDeviceCallRequest) {
|
||||
const { deviceName, data } = requestData;
|
||||
if (deviceName !== "grinklers") {
|
||||
// error handling? or just get the right device
|
||||
return false;
|
||||
}
|
||||
const request = schema.requests.deserializeRequest(data);
|
||||
return device.makeRequest(request);
|
||||
}
|
||||
|
||||
async function deviceCallRequest(socket: WebSocket, data: ws.IDeviceCallRequest): Promise<void> {
|
||||
let response: requests.Response | false;
|
||||
try {
|
||||
response = await doDeviceCallRequest(data);
|
||||
} catch (err) {
|
||||
response = err;
|
||||
}
|
||||
if (response) {
|
||||
const resData: ws.IDeviceCallResponse = {
|
||||
type: "deviceCallResponse",
|
||||
id: data.id,
|
||||
data: response,
|
||||
};
|
||||
socket.send(JSON.stringify(resData));
|
||||
}
|
||||
}
|
||||
|
||||
function webSocketHandler(socket: WebSocket) {
|
||||
const stop = autorun(() => {
|
||||
const json = serialize(schema.sprinklersDevice, device);
|
||||
log.trace({ device: json });
|
||||
const data = { type: "deviceUpdate", name: "grinklers", data: json };
|
||||
socket.send(JSON.stringify(data));
|
||||
}, { delay: 100 });
|
||||
socket.on("message", (socketData: WebSocket.Data) => {
|
||||
if (typeof socketData !== "string") {
|
||||
return log.error({ type: typeof socketData }, "received invalid socket data type from client");
|
||||
}
|
||||
let data: ws.IClientMessage;
|
||||
try {
|
||||
data = JSON.parse(socketData);
|
||||
} catch (err) {
|
||||
return log.error({ event, err }, "received invalid websocket message from client");
|
||||
}
|
||||
switch (data.type) {
|
||||
case "deviceCallRequest":
|
||||
deviceCallRequest(socket, data);
|
||||
break;
|
||||
default:
|
||||
return log.warn({ data }, "received invalid client message type");
|
||||
}
|
||||
});
|
||||
socket.on("close", () => stop());
|
||||
}
|
||||
import {state} from "./state";
|
||||
import {handler as webSocketHandler} from "./websocket";
|
||||
|
||||
const port = +(process.env.PORT || 8080);
|
||||
const host = process.env.HOST || "0.0.0.0";
|
||||
|
||||
const server = new Server(app);
|
||||
const webSocketServer = new WebSocket.Server({ server });
|
||||
const webSocketServer = new WebSocket.Server({server});
|
||||
|
||||
webSocketServer.on("connection", webSocketHandler);
|
||||
|
||||
state.start();
|
||||
server.listen(port, host, () => {
|
||||
log.info(`listening at ${host}:${port}`);
|
||||
});
|
||||
|
16
server/state.ts
Normal file
16
server/state.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import {SprinklersDevice} from "@common/sprinklers";
|
||||
import * as mqtt from "@common/sprinklers/mqtt";
|
||||
|
||||
export class State {
|
||||
mqttClient!: mqtt.MqttApiClient;
|
||||
device!: SprinklersDevice;
|
||||
|
||||
start() {
|
||||
this.mqttClient = new mqtt.MqttApiClient("mqtt://localhost:1883");
|
||||
this.device = this.mqttClient.getDevice("grinklers");
|
||||
|
||||
this.mqttClient.start();
|
||||
}
|
||||
}
|
||||
|
||||
export const state: State = new State();
|
65
server/websocket/index.ts
Normal file
65
server/websocket/index.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { autorun } from "mobx";
|
||||
import { serialize } from "serializr";
|
||||
import * as WebSocket from "ws";
|
||||
|
||||
import log from "@common/logger";
|
||||
import * as requests from "@common/sprinklers/requests";
|
||||
import * as schema from "@common/sprinklers/schema";
|
||||
import * as ws from "@common/sprinklers/websocketData";
|
||||
|
||||
import {state} from "../state";
|
||||
|
||||
async function doDeviceCallRequest(requestData: ws.IDeviceCallRequest) {
|
||||
const { deviceName, data } = requestData;
|
||||
if (deviceName !== "grinklers") {
|
||||
// error handling? or just get the right device
|
||||
return false;
|
||||
}
|
||||
const request = schema.requests.deserializeRequest(data);
|
||||
return state.device.makeRequest(request);
|
||||
}
|
||||
|
||||
async function deviceCallRequest(socket: WebSocket, data: ws.IDeviceCallRequest): Promise<void> {
|
||||
let response: requests.Response | false;
|
||||
try {
|
||||
response = await doDeviceCallRequest(data);
|
||||
} catch (err) {
|
||||
response = err;
|
||||
}
|
||||
if (response) {
|
||||
const resData: ws.IDeviceCallResponse = {
|
||||
type: "deviceCallResponse",
|
||||
id: data.id,
|
||||
data: response,
|
||||
};
|
||||
socket.send(JSON.stringify(resData));
|
||||
}
|
||||
}
|
||||
|
||||
export function handler(socket: WebSocket) {
|
||||
const stop = autorun(() => {
|
||||
const json = serialize(schema.sprinklersDevice, state.device);
|
||||
log.trace({ device: json });
|
||||
const data = { type: "deviceUpdate", name: "grinklers", data: json };
|
||||
socket.send(JSON.stringify(data));
|
||||
}, { delay: 100 });
|
||||
socket.on("message", (socketData: WebSocket.Data) => {
|
||||
if (typeof socketData !== "string") {
|
||||
return log.error({ type: typeof socketData }, "received invalid socket data type from client");
|
||||
}
|
||||
let data: ws.IClientMessage;
|
||||
try {
|
||||
data = JSON.parse(socketData);
|
||||
} catch (err) {
|
||||
return log.error({ event, err }, "received invalid websocket message from client");
|
||||
}
|
||||
switch (data.type) {
|
||||
case "deviceCallRequest":
|
||||
deviceCallRequest(socket, data);
|
||||
break;
|
||||
default:
|
||||
return log.warn({ data }, "received invalid client message type");
|
||||
}
|
||||
});
|
||||
socket.on("close", () => stop());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user