mirror of
https://github.com/pavlobu/deskreen.git
synced 2025-05-28 05:10:09 -07:00
serve client viewer on same port as socket server
This commit is contained in:
parent
68a5dd82da
commit
114c363817
5
.codecov.yml
Normal file
5
.codecov.yml
Normal file
@ -0,0 +1,5 @@
|
||||
coverage:
|
||||
status:
|
||||
patch:
|
||||
default:
|
||||
enabled: no
|
2
.github/workflows/codecov.yml
vendored
2
.github/workflows/codecov.yml
vendored
@ -1,5 +1,5 @@
|
||||
name: codecov generate
|
||||
on: [push, pull_request]
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-18.04
|
||||
|
5
app/client/.codecov.yml
Normal file
5
app/client/.codecov.yml
Normal file
@ -0,0 +1,5 @@
|
||||
coverage:
|
||||
status:
|
||||
patch:
|
||||
default:
|
||||
enabled: no
|
@ -17,7 +17,7 @@ import { autoUpdater } from 'electron-updater';
|
||||
import log from 'electron-log';
|
||||
import config from './configs/app.config';
|
||||
import i18n from './configs/i18next.config';
|
||||
import signalingServer from './server/signalingServer';
|
||||
import signalingServer from './server';
|
||||
import MenuBuilder from './menu';
|
||||
|
||||
const globalAny: any = global;
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
|
||||
import config from './configs/app.config';
|
||||
|
||||
import signalingServer from './server/signalingServer';
|
||||
import signalingServer from './server';
|
||||
|
||||
interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
|
||||
selector?: string;
|
||||
|
@ -1,37 +1,128 @@
|
||||
/* eslint-disable no-console */
|
||||
import { Server } from 'http';
|
||||
// import express, { Request, Response, NextFunction } from 'express';
|
||||
import http, { Server } from 'http';
|
||||
import express from 'express';
|
||||
import Koa from 'koa';
|
||||
import Io from 'socket.io';
|
||||
import cors from 'kcors';
|
||||
import Router from 'koa-router';
|
||||
import crypto from 'crypto';
|
||||
import koaStatic from 'koa-static';
|
||||
import koaSend from 'koa-send';
|
||||
import getPort from 'get-port';
|
||||
// import * as bodyParser from "body-parser";
|
||||
// import express from "express";
|
||||
// import { Routes } from "./routes";
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import Socket from './socket';
|
||||
import pollForInactiveRooms from './inactive_rooms';
|
||||
import getStore from './store';
|
||||
|
||||
let isDev;
|
||||
try {
|
||||
// eslint-disable-next-line global-require
|
||||
isDev = require('electron-is-dev');
|
||||
} catch (e) {
|
||||
isDev = true;
|
||||
}
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
const app = new Koa();
|
||||
|
||||
const router = new Router();
|
||||
|
||||
const store = getStore();
|
||||
|
||||
app.use(cors());
|
||||
app.use(router.routes());
|
||||
|
||||
function setStaticFileHeaders(
|
||||
ctx: Koa.ParameterizedContext<Koa.DefaultState, Koa.DefaultContext>
|
||||
) {
|
||||
ctx.set({
|
||||
'strict-transport-security': 'max-age=31536000',
|
||||
'X-Frame-Options': 'deny',
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'Referrer-Policy': 'no-referrer',
|
||||
'Feature-Policy':
|
||||
"geolocation 'none'; vr 'none'; payment 'none'; microphone 'none'",
|
||||
});
|
||||
}
|
||||
|
||||
const clientDistDirectory = isDev
|
||||
? `${__dirname}/../client/build`
|
||||
: `${__dirname}/client/build`;
|
||||
|
||||
if (clientDistDirectory) {
|
||||
app.use(async (ctx, next) => {
|
||||
setStaticFileHeaders(ctx);
|
||||
await koaStatic(clientDistDirectory)(ctx, next);
|
||||
});
|
||||
|
||||
app.use(async (ctx) => {
|
||||
setStaticFileHeaders(ctx);
|
||||
await koaSend(ctx, 'index.html', { root: clientDistDirectory });
|
||||
});
|
||||
} else {
|
||||
app.use(async (ctx) => {
|
||||
ctx.body = { ready: true };
|
||||
});
|
||||
}
|
||||
|
||||
const protocol = http;
|
||||
|
||||
const server = protocol.createServer(app.callback());
|
||||
const io = Io(server, {
|
||||
pingInterval: 20000,
|
||||
pingTimeout: 5000,
|
||||
serveClient: false,
|
||||
});
|
||||
|
||||
const getRoomIdHash = (id: string) => {
|
||||
return crypto.createHash('sha256').update(id).digest('hex');
|
||||
};
|
||||
|
||||
io.on('connection', async (socket) => {
|
||||
const { roomId } = socket.handshake.query;
|
||||
|
||||
const roomIdHash = getRoomIdHash(roomId);
|
||||
|
||||
let room = await store.get('rooms', roomIdHash);
|
||||
room = JSON.parse(room || '{}');
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Socket({
|
||||
roomIdOriginal: roomId,
|
||||
roomId: roomIdHash,
|
||||
socket,
|
||||
room,
|
||||
});
|
||||
});
|
||||
|
||||
const init = async (PORT: number) => {
|
||||
pollForInactiveRooms();
|
||||
|
||||
return server.listen(PORT, () => {
|
||||
console.log(`Signaling server is online at port ${PORT}`);
|
||||
});
|
||||
};
|
||||
|
||||
class SignalingServer {
|
||||
private static instance: SignalingServer;
|
||||
|
||||
public expressApp: express.Application;
|
||||
|
||||
public count: number;
|
||||
|
||||
public server: Server;
|
||||
|
||||
public port: number;
|
||||
// public routePrv: Routes = new Routes();
|
||||
|
||||
constructor() {
|
||||
this.expressApp = express();
|
||||
this.count = 0;
|
||||
this.config();
|
||||
this.server = new Server();
|
||||
this.port = 3131;
|
||||
// this.routePrv.routes(this.app);
|
||||
}
|
||||
|
||||
public async start(): Promise<Server> {
|
||||
// this.port = await getRandomPort();
|
||||
this.port = await getPort({ port: 3131 });
|
||||
this.server = this.expressApp.listen(this.port);
|
||||
this.server = await init(this.port);
|
||||
console.log(`\n\nDeskreen signaling server started at port: ${this.port}`);
|
||||
return this.server;
|
||||
}
|
||||
@ -40,25 +131,6 @@ class SignalingServer {
|
||||
this.server.close();
|
||||
}
|
||||
|
||||
private config(): void {
|
||||
// support application/json type post data
|
||||
// this.app.use(bodyParser.json());
|
||||
// support application/x-www-form-urlencoded post data
|
||||
// this.app.use(bodyParser.urlencoded({ extended: false }));
|
||||
// responde with indented JSON string
|
||||
// this.app.set("json spaces", 2);
|
||||
this.expressApp.get('/', (_, res) => {
|
||||
this.count += 1;
|
||||
res.status(200);
|
||||
res.write('Deskreen signaling server is running');
|
||||
res.send();
|
||||
});
|
||||
this.expressApp.get('/favicon.ico', (_, res) => {
|
||||
res.status(204);
|
||||
res.send();
|
||||
});
|
||||
}
|
||||
|
||||
public static getInstance(): SignalingServer {
|
||||
if (!SignalingServer.instance) {
|
||||
SignalingServer.instance = new SignalingServer();
|
||||
@ -68,4 +140,6 @@ class SignalingServer {
|
||||
}
|
||||
}
|
||||
|
||||
export const getIO = () => io;
|
||||
|
||||
export default SignalingServer.getInstance();
|
||||
|
@ -1,212 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
import http, { Server } from 'http';
|
||||
import express from 'express';
|
||||
import https from 'https';
|
||||
import Koa from 'koa';
|
||||
import Io from 'socket.io';
|
||||
import cors from 'kcors';
|
||||
import Router from 'koa-router';
|
||||
import crypto from 'crypto';
|
||||
// import koaStatic from 'koa-static';
|
||||
import koaSend from 'koa-send';
|
||||
import getPort from 'get-port';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import Socket from './socket';
|
||||
import pollForInactiveRooms from './inactive_rooms';
|
||||
import getStore from './store';
|
||||
|
||||
let isDev;
|
||||
try {
|
||||
// eslint-disable-next-line global-require
|
||||
isDev = require('electron-is-dev');
|
||||
} catch (e) {
|
||||
isDev = true;
|
||||
}
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
|
||||
const app = new Koa();
|
||||
// const PORT = process.env.PORT || 3001;
|
||||
|
||||
const router = new Router();
|
||||
|
||||
// const appName = process.env.HEROKU_APP_NAME ? process.env.HEROKU_APP_NAME : '';
|
||||
// const isReviewApp = /-pr-/.test(appName);
|
||||
// const siteURL = process.env.SITE_URL;
|
||||
|
||||
const store = getStore();
|
||||
|
||||
// if ((siteURL || env === 'development') && !isReviewApp) {
|
||||
// app.use(
|
||||
// cors({
|
||||
// origin: env === 'development' ? '*' : siteURL,
|
||||
// allowMethods: ['GET', 'HEAD', 'POST'],
|
||||
// credentials: true,
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
app.use(cors());
|
||||
app.use(router.routes());
|
||||
|
||||
const apiHost = process.env.API_HOST;
|
||||
const cspDefaultSrc = `'self'${
|
||||
apiHost ? ` https://${apiHost} wss://${apiHost}` : ''
|
||||
}`;
|
||||
|
||||
function setStaticFileHeaders(
|
||||
ctx: Koa.ParameterizedContext<Koa.DefaultState, Koa.DefaultContext>
|
||||
) {
|
||||
ctx.set({
|
||||
'strict-transport-security': 'max-age=31536000',
|
||||
'Content-Security-Policy': `default-src ${cspDefaultSrc} 'unsafe-inline'; img-src 'self' data:;`,
|
||||
'X-Frame-Options': 'deny',
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'Referrer-Policy': 'no-referrer',
|
||||
'Feature-Policy':
|
||||
"geolocation 'none'; vr 'none'; payment 'none'; microphone 'none'",
|
||||
});
|
||||
}
|
||||
|
||||
const clientDistDirectory = isDev
|
||||
? `${__dirname}/../client/build`
|
||||
: `${__dirname}/client/build`;
|
||||
|
||||
if (clientDistDirectory) {
|
||||
app.use(async (ctx) => {
|
||||
setStaticFileHeaders(ctx);
|
||||
// await koaStatic(clientDistDirectory, {
|
||||
// maxage: ctx.req.url === '/' ? 60 * 1000 : 365 * 24 * 60 * 60 * 1000, // one minute in ms for html doc, one year for css, js, etc
|
||||
// })(ctx, next);
|
||||
});
|
||||
|
||||
app.use(async (ctx) => {
|
||||
setStaticFileHeaders(ctx);
|
||||
await koaSend(ctx, 'index.html', { root: clientDistDirectory });
|
||||
});
|
||||
} else {
|
||||
app.use(async (ctx) => {
|
||||
ctx.body = { ready: true };
|
||||
});
|
||||
}
|
||||
|
||||
const protocol = (process.env.PROTOCOL || 'http') === 'http' ? http : https;
|
||||
|
||||
const server = protocol.createServer(app.callback());
|
||||
const io = Io(server, {
|
||||
pingInterval: 20000,
|
||||
pingTimeout: 5000,
|
||||
serveClient: false,
|
||||
});
|
||||
|
||||
// Only use socket adapter if store has one
|
||||
// if (store.hasSocketAdapter) {
|
||||
// io.adapter(store.getSocketAdapter());
|
||||
// }
|
||||
|
||||
const roomHashSecret = process.env.ROOM_HASH_SECRET;
|
||||
|
||||
const getRoomIdHash = (id: string) => {
|
||||
if (env === 'development') {
|
||||
return id;
|
||||
}
|
||||
|
||||
if (roomHashSecret) {
|
||||
return crypto.createHmac('sha256', roomHashSecret).update(id).digest('hex');
|
||||
}
|
||||
|
||||
return crypto.createHash('sha256').update(id).digest('hex');
|
||||
};
|
||||
|
||||
export const getIO = () => io;
|
||||
|
||||
io.on('connection', async (socket) => {
|
||||
const { roomId } = socket.handshake.query;
|
||||
|
||||
const roomIdHash = getRoomIdHash(roomId);
|
||||
|
||||
let room = await store.get('rooms', roomIdHash);
|
||||
room = JSON.parse(room || '{}');
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Socket({
|
||||
roomIdOriginal: roomId,
|
||||
roomId: roomIdHash,
|
||||
socket,
|
||||
room,
|
||||
});
|
||||
});
|
||||
|
||||
const init = async (PORT: number) => {
|
||||
pollForInactiveRooms();
|
||||
|
||||
return server.listen(PORT, () => {
|
||||
console.log(`Signaling server is online at port ${PORT}`);
|
||||
});
|
||||
};
|
||||
|
||||
class SignalingServer {
|
||||
private static instance: SignalingServer;
|
||||
|
||||
public expressApp: express.Application;
|
||||
|
||||
public count: number;
|
||||
|
||||
public server: Server;
|
||||
|
||||
public port: number;
|
||||
// public routePrv: Routes = new Routes();
|
||||
|
||||
constructor() {
|
||||
this.expressApp = express();
|
||||
this.count = 0;
|
||||
this.config();
|
||||
this.server = new Server();
|
||||
this.port = 3131;
|
||||
// this.routePrv.routes(this.app);
|
||||
}
|
||||
|
||||
public async start(): Promise<Server> {
|
||||
// this.port = await getRandomPort();
|
||||
this.port = await getPort({ port: 3131 });
|
||||
this.server = await init(this.port);
|
||||
console.log(`\n\nDeskreen signaling server started at port: ${this.port}`);
|
||||
return this.server;
|
||||
}
|
||||
|
||||
public stop(): void {
|
||||
this.server.close();
|
||||
}
|
||||
|
||||
private config(): void {
|
||||
// support application/json type post data
|
||||
// this.app.use(bodyParser.json());
|
||||
// support application/x-www-form-urlencoded post data
|
||||
// this.app.use(bodyParser.urlencoded({ extended: false }));
|
||||
// responde with indented JSON string
|
||||
// this.app.set("json spaces", 2);
|
||||
this.expressApp.get('/', (_, res) => {
|
||||
this.count += 1;
|
||||
res.status(200);
|
||||
res.write('Deskreen signaling server is running');
|
||||
res.send();
|
||||
});
|
||||
this.expressApp.get('/favicon.ico', (_, res) => {
|
||||
res.status(204);
|
||||
res.send();
|
||||
});
|
||||
}
|
||||
|
||||
public static getInstance(): SignalingServer {
|
||||
if (!SignalingServer.instance) {
|
||||
SignalingServer.instance = new SignalingServer();
|
||||
}
|
||||
|
||||
return SignalingServer.instance;
|
||||
}
|
||||
}
|
||||
|
||||
export default SignalingServer.getInstance();
|
@ -2,7 +2,7 @@
|
||||
import _ from 'lodash';
|
||||
import Io from 'socket.io';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import { getIO } from './signalingServer';
|
||||
import { getIO } from '.';
|
||||
import getStore from './store';
|
||||
|
||||
interface User {
|
||||
@ -82,24 +82,12 @@ export default class Socket implements SocketOPTS {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
joinRoom(roomId: string, socket: Io.Socket) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (getStore().hasSocketAdapter) {
|
||||
// TODO: what is this?
|
||||
// getIO()
|
||||
// .of('/')
|
||||
// .adapter.remoteJoin(socket.id, roomId, (err: Error) => {
|
||||
// if (err) {
|
||||
// reject();
|
||||
// }
|
||||
// resolve();
|
||||
// });
|
||||
} else {
|
||||
socket.join(roomId, (err) => {
|
||||
if (err) {
|
||||
reject();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
socket.join(roomId, (err) => {
|
||||
if (err) {
|
||||
reject();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
"build-client": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn build",
|
||||
"dev": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && concurrently \"cross-env START_HOT=1 yarn start-renderer-dev\" \"yarn start-client-dev\"",
|
||||
"coverage": "cross-env BABEL_DISABLE_CACHE=1 jest --coverage && yarn coverage-client",
|
||||
"coverage-client": "cd app/client && SKIP_PREFLIGHT_CHECK=true cross-env BABEL_DISABLE_CACHE=1 yarn test -- --coverage --watchAll=false",
|
||||
"coverage-client": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true cross-env BABEL_DISABLE_CACHE=1 yarn test -- --coverage --watchAll=false",
|
||||
"electron-rebuild": "electron-rebuild --parallel --force --types prod,dev,optional --module-dir app",
|
||||
"install-client:nolockfile": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn install --no-lockfile",
|
||||
"install-client:frozenlockfile": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn install --frozen-lockfile",
|
||||
@ -21,7 +21,7 @@
|
||||
"lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss",
|
||||
"lint-styles-fix": "yarn --silent lint-styles --fix; exit 0",
|
||||
"package": "yarn build && electron-builder build --publish never",
|
||||
"package-all": "yarn build && electron-builder build -mwl",
|
||||
"package-all": "yarn build && electron-builder build -mwl --publish never",
|
||||
"package-ci": "yarn postinstall && yarn build && electron-builder --publish never",
|
||||
"package-mac": "yarn build && electron-builder build --mac",
|
||||
"package-linux": "yarn build && electron-builder build --linux",
|
||||
@ -37,7 +37,7 @@
|
||||
"start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js",
|
||||
"start-client-dev": "cd app/client && cross-env SKIP_PREFLIGHT_CHECK=true yarn start",
|
||||
"test": "cross-env BABEL_DISABLE_CACHE=1 jest && yarn test-client",
|
||||
"test-client": "cd app/client && SKIP_PREFLIGHT_CHECK=true cross-env BABEL_DISABLE_CACHE=1 yarn test:nowatch",
|
||||
"test-client": "cd app/client && cross-env BABEL_DISABLE_CACHE=1 SKIP_PREFLIGHT_CHECK=true yarn test:nowatch",
|
||||
"test-all": "yarn lint && yarn tsc && yarn build && yarn test",
|
||||
"test-e2e": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe electron:./app ./test/e2e/HomePage.e2e.ts",
|
||||
"test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe --live electron:./app ./test/e2e/HomePage.e2e.ts",
|
||||
|
Loading…
x
Reference in New Issue
Block a user