documentation replaced

This commit is contained in:
C
2023-01-10 18:14:21 +05:00
parent b11e2536cb
commit 108878447d
31 changed files with 2 additions and 315175 deletions
+67
View File
@@ -0,0 +1,67 @@
const {
config_path,
routes_path,
init_log_path,
runtime_log_path
} = require(process.argv[process.argv.length - 1])
const config = require(config_path)
const express = require('express')
const logger = require('./lib/logger')
const routes = require(routes_path)
const helmet = require('helmet')
// loggers
const logger_init = new logger(init_log_path)
const logger_runtime = new logger(runtime_log_path)
const app = express()
app.use(helmet())
// logger
app.use(function(req, res, next) {
var {url} = req
logger_runtime.log(url)
next()
})
// CORS
app.options(function(req, res) {
//'GET, POST, OPTIONS, PUT, PATCH, DELETE'
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST')
res.end()
})
app.use(function (req, res, next) {
const {origin} = req.headers
if (config.cors.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin)
}
res.setHeader('Access-Control-Allow-Credentials', true)
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type')
next()
})
//routes
app.use(routes)
// errors handlers
app.use(function(error, req, res, next) {
// errors
logger_runtime.error(error)
res.status(400).json({type:'error', content:error.message})
next()
})
app.use(function(req, res, next) {
res.end()
})
// start listen server
try {
app.listen(config.port)
logger_init.log(`Listening at http://localhost:${config.port}`)
} catch (e) {
return logger_init.error(e)
}
+6
View File
@@ -0,0 +1,6 @@
{
"config_path":"./coordinator/config.json",
"routes_path":"./coordinator/routes",
"init_log_path":"./logs/coordinator_init.log",
"runtime_log_path":"./logs/coordinator_runtime.log"
}
+6
View File
@@ -0,0 +1,6 @@
{
"config_path":"./session_server/config.json",
"routes_path":"./session_server/routes",
"init_log_path":"./logs/session_server_init.log",
"runtime_log_path":"./logs/session_server_runtime.log"
}
+12
View File
@@ -0,0 +1,12 @@
{
"port" : "3001",
"mongodb_url" : "mongodb://pixel_admin:!G3432664499@192.168.1.163:27017",
"database_name" : "pixel_streaming",
"cors":[
"http://192.168.1.171:3000",
"http://localhost:3000",
"https://stream.graff.tech/",
"http://212.220.216.185:3005",
"https://stream.graff.tech"
]
}
+100
View File
@@ -0,0 +1,100 @@
const db_connection = require('../database/connection.js')
// two bad headers
const http_client = require('../../lib/http_client.js')
const crypto = require('crypto')
const plan_session = async (req, res, next) => {
//var session_sheduled = database.collection('session_sheduled')
//var sessions = await session_sheduled.find().toArray()
//callback(response)
}
const create_session = async (req, res, next) => {
//create?title=name&next_var=0
try {
const db = await db_connection.get_db()
var servers = await db.collection('session_server').find({'title':req.query.title}).toArray()
if (!servers.length)
throw new Error('servers not found')
// find free server and create session
var session_active = db.collection('session_active')
var free_server
var servers_length = servers.length
for (var i = 0; i < servers_length; ++i) {
var sessions = await session_active.find({'server_id':servers[i].server_id}).toArray()
if (servers[i].limit > sessions.length) {
free_server = servers[i]
break
}
}
if (!free_server)
throw new Error('session limit reached')
var session_id = crypto.randomBytes(16).toString('hex')
// create session on session server
http_client.get({
host: free_server.ip,
port: free_server.port,
path: `/session/create?title=${req.query.title}&session_id=${session_id}`
}, async function(answer) {
try {
answer = JSON.parse(answer)
//console.log(answer.method)
if (!answer.link)
throw new Error('session not created')
// generate random code for session access
var code = Math.floor(1000 + Math.random() * 9000)
while ((await session_active.find({'code':code}).toArray()).length) {
code = Math.floor(1000 + Math.random() * 9000)
}
// add session to database
await session_active.insertOne({
server_id:free_server.server_id,
session_id:session_id,
connection_link:answer.link,
connection_code:code
})
// SHALL REMOVE CONNECTION CODE BECAUSE IN WEB WE DO NOT NEED IT
res.json({msg:'SESSION_CREATED', link:answer.link, connection_code:code})
} catch (e) {
next(e)
}
}, function(err) {
next(Error('session server not working'))
})
} catch (e) {
next(e)
}
}
const connect_session = async (req, res, next) => {
try {
const db = await db_connection.get_db()
var session = await db.collection('session_active').findOne({connection_code:parseInt(req.query.connection_code)})
if (!session)
throw new Error('sessions not found')
res.json({msg:'SESSION_DATA', link:session.connection_link, connection_code:session.connection_code})
} catch (e) {
next (e)
}
}
const close_session = async (req, res, next) => {
const db = await db_connection.get_db()
await db.collection('session_active').deleteOne({session_id:req.query.session_id})
res.json({msg:"SESSION_CLOSED", session_id:req.session_id})
}
module.exports = {
plan_session,
create_session,
connect_session,
close_session
}
@@ -0,0 +1,14 @@
const db_connection = require('../database/connection.js')
const crypto = require('crypto')
const emergency_shutdown = async (req, res, next) => {
const db = await db_connection.get_db()
var id = req.query.id
var query = {server_id:{$in:[id]}}
await db.collection('session_active').deleteMany(query)
res.json({msg:'SESSIONS_CLOSED'})
}
module.exports = {
emergency_shutdown
}
+16
View File
@@ -0,0 +1,16 @@
const config = require('../config.json')
const db_connection = require('../database/connection.js')
const get_titles = async (req, res, next) => {
try {
const db = await db_connection.get_db()
var titles = await db.collection('title').find().skip(parseInt(req.query.start)).limit(parseInt(req.query.count)).toArray()
res.json(titles)
} catch (e) {
next(e)
}
}
module.exports = {
get_titles
}
+17
View File
@@ -0,0 +1,17 @@
const { MongoClient } = require("mongodb")
const { mongodb_url, database_name } = require('../config.json')
const client = new MongoClient(mongodb_url)
let database
// throw exception
module.exports.get_db = async () => {
try {
await client.connect()
database = client.db(database_name)
} catch (e) {
throw e
}
return database
}
+10
View File
@@ -0,0 +1,10 @@
const router = require('express').Router()
const router_title = require('./title')
const router_session = require('./session')
const router_session_server = require('./session_server')
router.use('/title', router_title)
router.use('/session', router_session)
router.use('/session_server', router_session_server)
module.exports = router
+10
View File
@@ -0,0 +1,10 @@
const router = require('express').Router()
const {plan_session, create_session, connect_session, close_session} = require('../controller/session')
router.get('/plan', plan_session)
router.get('/create', create_session)
router.get('/connect', connect_session)
router.get('/close', close_session)
module.exports = router
+7
View File
@@ -0,0 +1,7 @@
const router = require('express').Router()
const {emergency_shutdown} = require('../controller/session_server')
router.get('/emergency_shutdown', emergency_shutdown)
module.exports = router
+7
View File
@@ -0,0 +1,7 @@
const router = require('express').Router()
const {get_titles} = require('../controller/title')
router.get('/get', get_titles)
module.exports = router
+81
View File
@@ -0,0 +1,81 @@
const http = require('http')
const https = require('https')
module.exports = class http_client {
constructor(ip, port) {
this.#ip = ip
this.#port = port
}
async post(data, callback_answer, callback_error) {
// Build the post string from an object
// An object of options to indicate where to post to
var post_options = {
host: this.#ip,
port: this.#port,
method: 'POST',
headers: {
'Content-Type': 'applicaiton/json',
'Content-Length': Buffer.byteLength(data)
}
}
// Set up the request
var request = http.request(post_options, function(res) {
res.setEncoding('utf8')
res.on('data', async function (answer) {
callback_answer(answer)
})
})
request.on('error', function(e) {
callback_error(e)
})
// post the data
request.write(data)
request.end()
}
#ip
#port
}
module.exports.post = async (options, callback_res, callback_err) => {
http.post(options, function(res) {
var body_chunks = []
res.on('data', chunk => {
body_chunks.push(chunk)
}).on('end', () => {
var body = Buffer.concat(body_chunks)
callback_res(body)
})
}).on('error', err => {
callback_err(err)
})
}
module.exports.get = async (options, callback_res, callback_err) => {
http.get(options, function(res) {
var body_chunks = []
res.on('data', chunk => {
body_chunks.push(chunk)
}).on('end', () => {
var body = Buffer.concat(body_chunks)
callback_res(body)
})
}).on('error', err => {
callback_err(err)
})
}
module.exports.gets = async (options, callback_res, callback_err) => {
https.get(options, function(res) {
var body_chunks = []
res.on('data', chunk => {
body_chunks.push(chunk)
}).on('end', () => {
var body = Buffer.concat(body_chunks)
callback_res(body)
})
}).on('error', err => {
callback_err(err)
})
}
+34
View File
@@ -0,0 +1,34 @@
const fs = require('fs')
const path = require('path')
const node_time = require('node-datetime')
const util = require('util')
module.exports = class logger {
constructor(filepath) {
this.#filepath = filepath
this.#filename = path.basename(filepath)
var dirname = path.dirname(filepath)
if (!fs.existsSync(dirname))
fs.mkdirSync(dirname, {recursive:true})
}
error(...arg) {
this.#log('error', arg)
}
log(...arg) {
this.#log('', arg)
}
#log(message = '', ...arg) {
var args = ''
arg.forEach(value => {
args += util.format(value) + ' '
})
args = (node_time.create().format('d-m-Y H:M:S')).toString() + ((message != '') ? ': ' + message : '') + ': ' + args
console.log(this.#filename + ': ' + args)
fs.appendFileSync(this.#filepath, args + '\n')
}
#filepath
#filename
}
+47
View File
@@ -0,0 +1,47 @@
class port {
constructor(value) {
this.#value = value
this.#free = true
}
get_value() {
return this.#value
}
set_free() {
this.#free = true
}
set_busy() {
this.#free = false
}
is_free() {
return this.#free
}
#value
#free
}
module.exports = class port_alloc {
constructor(port_begin, count) {
this.#ports = new Array()
for (var i = port_begin; i < port_begin + count; ++i) {
this.#ports.push(new port(i))
}
}
get() {
for (var i in this.#ports) {
if (this.#ports[i].is_free()) {
this.#ports[i].set_busy()
return this.#ports[i].get_value()
}
}
throw new Error('no free ports')
}
free(busy_port) {
for (var i in this.#ports) {
if (this.#ports[i].get_value() == busy_port) {
this.#ports[i].set_free()
return
}
}
}
#ports
}
+4009
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
{
"name": "coordinator",
"version": "1.0.0",
"description": "",
"main": "coordinator.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"cors": "^2.8.5",
"experss": "^0.0.1-security",
"express": "^4.18.2",
"helmet": "^6.0.1",
"https": "^1.0.0",
"mongodb": "^4.12.0",
"mongoose": "^6.8.0",
"node-datetime": "^2.1.2",
"winston": "^3.8.2"
}
}
+4
View File
@@ -0,0 +1,4 @@
:: Copyright Graff Interactive, Inc. All Rights Reserved.
@echo off
set config_name=config_coordinator.json
start node "%~dp0app.js" "%~dp0%config_name%"
+4
View File
@@ -0,0 +1,4 @@
:: Copyright Graff Interactive, Inc. All Rights Reserved.
@echo off
set config_name=config_session_server.json
start node "%~dp0app.js" "%~dp0%config_name%"
+30
View File
@@ -0,0 +1,30 @@
{
"port":3002,
"external_domain":"a1.session.graff.tech",
"coordinator_domain":"a1.coord.graff.tech",
"server_id":"1acd21dc6b70961f10ad134fb6403985",
"session_ports":{
"app_begin":47500,
"http_begin":47000
},
"start_nginx":115,
"cors":[
"a1.coord.graff.tech",
"http://192.168.1.115"
],
"webrtc_args_static":{
"cirrus_path":"D:/shared/Builds/Ivaz_Optimized_2/Samples/PixelStreaming/WebServers/SignallingWebServer/cirrus.js"
},
"app_args_runtime":{
"ip":"-PixelStreamingIP=",
"port":"-PixelStreamingPort="
},
"app_args_static":[
"-RenderOffScreen",
"-PixelStreamingEncoderMaxBitrate=15000000",
"-ResX 1280 -ResY 720",
"-PixelStreamingEncoderMinQP=25",
"-PixelStreamingEncoderMultipass=QUARTER",
"-PixelStreamingWebRTCMaxFps=60"
]
}
+117
View File
@@ -0,0 +1,117 @@
const port_alloc = require('../../lib/port_alloc.js')
const titles = require('../titles.json')
const config = require('../config.json')
const { spawn } = require('node:child_process')
const child_process = require('child_process')
const http_client = require('../../lib/http_client.js')
const app_port_begin = config.session_ports.app_begin
const http_port_begin = config.session_ports.http_begin
const app_args_static = config.app_args_static
const app_args_ip = config.app_args_runtime.ip
const server_ip = '127.0.0.1'//config.ip
const external_domain = config.external_domain
const app_args_port = config.app_args_runtime.port
const start_nginx = config.start_nginx
const server_id = config.server_id
const webrtc_cirrus_path = config.webrtc_args_static.cirrus_path
const coordinator_domain = config.coordinator_domain
// const http_client = require('../lib/http_client.js')
// SHALL FIX IT IN FUTURE BECAUSE IT IS NOT THE REST API
const ports_count = 50
var app_port_alloc = new port_alloc(app_port_begin, ports_count)
var http_port_alloc = new port_alloc(http_port_begin, ports_count)
// close all own sessions on session server if emergency shutdown
http_client.gets({
host: coordinator_domain,
path: `/session_server/emergency_shutdown?id=${server_id}`
}, async function(answer) {
}, function(err) {
//next(Error('session server not working'))
})
const create_session = async (req, res, next) => {
//create?title=name&next_var=0
try {
var app_info
titles.forEach((title) => {
if (title.title == req.query.title) {
app_info = title
}
})
if (!app_info)
throw new Error('app info not exists')
var app_port
var http_port
try {
app_port = app_port_alloc.get()
http_port = http_port_alloc.get()
} catch(e) {
//console.log('count error')
throw new Error(e)
}
// start app_proc
const app_proc = spawn(app_info.path, [].concat(app_args_static,
[app_args_ip + server_ip, app_args_port + app_port.toString()]), {
detached: true
})
app_proc.on('error', function(err) {
throw new Error('create proc error')
})
app_proc.on('close', (code) => {
app_port_alloc.free(app_port)
})
// start webrtc server
const webrtc_proc = child_process.fork(webrtc_cirrus_path, [http_port.toString(), app_port.toString()], {
detached: true
})
webrtc_proc.on('error', function(err) {
throw new Error('create webrtc error')
})
webrtc_proc.on('close', (code) => {
http_port_alloc.free(http_port)
// if webrtc server closed, kill app proc and send session end message to server
if (process.platform === 'win32') {
spawn('taskkill', ['/pid', app_proc.pid, '/f', '/t'])
}
else {
app_proc.kill('SIGINT')
}
http_client.gets({
host: coordinator_domain,
path: `/session/close?session_id=${req.query.session_id}`
}, async function(answer) {
}, function(err) {
next(Error('session server not working'))
})
})
setTimeout(() => {
res.json({msg:'SESSION_CREATED', link:`https://${external_domain}/${start_nginx}${http_port}/`})
}, 1000)
} catch (e) {
next(e)
}
}
const connect_session = async (req, res, next) => {
}
const close_session = async (req, res, next) => {
}
module.exports = {
create_session,
connect_session,
close_session
}
+6
View File
@@ -0,0 +1,6 @@
const router = require('express').Router()
const router_session = require('./session')
router.use('/session', router_session)
module.exports = router
+8
View File
@@ -0,0 +1,8 @@
const router = require('express').Router()
const {create_session, connect_session} = require('../controller/session')
router.get('/create', create_session)
router.get('/connect', connect_session)
module.exports = router
+14
View File
@@ -0,0 +1,14 @@
[
{
"title":"fortis",
"path":"D:/shared/Builds/Fortis_UnStable_64/WindowsNoEditor/FORTIS_Taktika.exe"
},
{
"title":"ivazowsky",
"path":"D:/shared/Builds/Ivaz_Optimized_2/Ivazowsky.exe"
},
{
"title":"mosharov",
"path":"D:/shared/Builds/mosharForStreaming/Masharovdev.exe"
}
]
+21
View File
@@ -0,0 +1,21 @@
var nginx_start = 10
var start_port = 47000
for (let i = 0; i < 20; i++) {
// console.log(` location /${nginx_start}${start_port+i} {`)
// console.log(` return 301 http://192.168.1.${nginx_start}:${start_port+i}/;`)
// console.log(` }`)
console.log(` location /${nginx_start}${start_port+i}/ {`)
console.log(` proxy_pass http://192.168.0.${nginx_start}:${start_port+i}/;`)
console.log(' proxy_set_header Upgrade $http_upgrade;')
console.log(` proxy_set_header Connection 'upgrade';`)
console.log(' }')
}
// location = /ombi {
// return 301 https://FQDN/ombi/;
// }
// setTimeout(() => {
// res.end('Hello World!');
// }, 10000);
+3
View File
@@ -0,0 +1,3 @@
let host = '5.141.82.116'
let port = '3002'
console.log(require('crypto').createHash('md5').update(`${host}${port}`).digest('hex'))