// Alternative thread. using HTTP server instead
const { resolve } = require('path');
class WSv {
constructor(options) {
this.options = options || {};
}
}
WSv.actions = {
echo: async function(data, req, res) {
console.log("response back:", data.post.msg);
res.write(data.post.msg);
},
run: async function(data, req, res) {
try {
if (data.post.type == "function") data.post.msg = `return (${data.post.msg})()`
let AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
var thisVal = new AsyncFunction(data.post.msg);
var result = await thisVal() || ""
res.write(result);
} catch (e) {
res.write("Error executing "+data.post.msg+"\n"+e.toString());
}
},
close: async function(data, req, res) {
window.close(true);
}
}
WSv.prototype.action = async function(action, data, req, res) {
if (!ThreadHost.actions[action]) return;
return await ThreadHost.actions[action].call(this, data, req, res)
}
WSv.prototype.closeServer = function() {
this.server.close();
}
WSv.prototype.startServer = function() {
var http = require('http');
var url = require('url');
var querystring = require('querystring');
var hostname = '127.0.0.1';
//this.port = 29942;
var collectRequestData = async function(request, callback) {
callback = callback || async function() {}
return new Promise(async (resolve, reject) => {
const FORM_URLENCODED = 'application/x-www-form-urlencoded';
if(request.headers['content-type'].includes(FORM_URLENCODED)) {
let body = '';
request.on('data', chunk => {
body += chunk.toString();
});
request.on('end', async () => {
await callback(querystring.parse(body));
resolve(querystring.parse(body));
});
}
else {
await callback(null);
resolve(null);
}
})
}
this.server = http.createServer(async (req, res) => {
console.log("Incoming connection:");
console.log("Request:", req);
console.log("response:", res);
var query;
var postData;
if (req.url.includes("?")) {
var queryStr = req.url.substring(req.url.indexOf("?")+1);
query = querystring.parse(queryStr);
console.log("query", query);
// close server if success
//this.server.close();
}
if (req.method === 'POST') {
postData = await collectRequestData(req);
console.log("Post data:", postData);
}
res.statusCode = 200;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Content-Type', 'text/plain');
if (query.action) {
await this.action(query.action, {post:postData, get:query}, req, res);
}
// end the response
res.end();
});
this.server.listen(this.port, hostname, () => {
this.setStatus(`Server running at http://${hostname}:${this.port}/`);
});
}
WSv.prototype.setStatus = function(str) {
$('[data-window="thread"] .status').html(str);
console.log(str);
}
/**
* @class
*/
class Thread {
constructor(options) {
this.options = options || {};
this.port = this.options.port || common.rand(30000, 40000);
while (Thread.list[this.port]) {
this.port = common.rand(30000, 40000);
}
Thread.list[this.port] = this;
}
}
Thread.list = [];
Thread.close = function() {
delete Thread.list[this.port];
}
Thread.prototype.setReadyState = function(state) {
this.isReady = state;
}
Thread.prototype.getReadyState = function(state) {
this.isReady = state;
}
Thread.prototype.openThreadWindow = async function() {
return new Promise((resolve, reject) => {
nw.Window.open("www/thread.html?port="+this.port, {new_instance:true}, (win) => {
console.log(arguments);
resolve();
});
})
}
Thread.prototype.send = async function(command, msg, options) {
options = options || {};
options.msg = msg || options.msg;
options.type = typeof options.msg;
if (options.type == "function") {
options.msg = options.msg.toString();
}
this.setReadyState(false);
return new Promise((resolve, reject) => {
$.post(`http://127.0.0.1:${this.port}/?action=${command}`, options, function(data) {
resolve(data);
})
.fail(function() {
reject();
})
.always(()=> {
this.setReadyState(true);
})
})
}
Thread.prototype.init = async function() {
}
/**
* Handle socket as a server
* @class
*/
var ThreadServer = function() {
this.threadList = Thread.list;
}
ThreadServer.prototype.distributeTask = async function(tasks=[]) {
if (Array.isArray(tasks) == false) tasks = [tasks]
}
/**
* Add task to the iddle process.
* If none is iddle, will wait until there is iddle process
*/
ThreadServer.prototype.addTask = async function() {
}
ThreadServer.actions = {
echo: async function(data, req, res) {
console.log("response back:", data.post.msg);
res.write(data.post.msg);
}
}
ThreadServer.prototype.action = async function(action, data, req, res) {
if (!ThreadServer.actions[action]) return;
return await ThreadServer.actions[action].call(this, data, req, res)
}
ThreadServer.prototype.startServer = function() {
var http = require('http');
var url = require('url');
var querystring = require('querystring');
var hostname = '127.0.0.1';
this.port = 41014;
var collectRequestData = async function(request, callback) {
callback = callback || async function() {}
return new Promise(async (resolve, reject) => {
const FORM_URLENCODED = 'application/x-www-form-urlencoded';
if(request.headers['content-type'].includes(FORM_URLENCODED)) {
let body = '';
request.on('data', chunk => {
body += chunk.toString();
});
request.on('end', async () => {
await callback(querystring.parse(body));
resolve(querystring.parse(body));
});
}
else {
await callback(null);
resolve(null);
}
})
}
this.server = http.createServer(async (req, res) => {
console.log("Incoming connection:");
console.log("Request:", req);
console.log("response:", res);
var query;
var postData;
if (req.url.includes("?")) {
var queryStr = req.url.substring(req.url.indexOf("?")+1);
query = querystring.parse(queryStr);
console.log("query", query);
// close server if success
//this.server.close();
}
if (req.method === 'POST') {
postData = await collectRequestData(req);
console.log("Post data:", postData);
}
res.statusCode = 200;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Content-Type', 'text/plain');
if (query.action) {
await this.action(query.action, {post:postData, get:query}, req, res);
}
// end the response
res.end();
});
this.server.listen(this.port, hostname, () => {
this.setStatus(`Server running at http://${hostname}:${this.port}/`);
});
}
/**
* Handle socket as a client
* @class
*/
class ThreadHost extends WSv {
constructor(options) {
super(options);
this.init();
}
}
ThreadHost.prototype.init = function() {
this.query = window.location.search.substr(1)
var searchparam = new URLSearchParams(this.query);
this.port = searchparam.get("port")
}
$(document).ready(function() {
if ($('body').is('[data-window="thread"]') == false) return;
window.threadHost = new ThreadHost();
threadHost.startServer();
})