Set up a server from within an electron app - node.js

I haven't had any success looking for this because I mostly find misleading questions, about people wanting to use data from a server inside of their electron app. That's not my case.
I have a regular app, which uses a server on the internet, just like any other, but we want to make it available for schools without internet (without any or without reliable internet), so what I'm trying to do is to create a version of my server which runs from an electron exe and serves files for the students conected to the wifi (but no the internet) to access. After the process is done "offline", I will sync the data from the electron app itself.
I tried to run a server from express but I didn't have any progress so far. What I tried was to put the exact same code from my node server in my main.js file and had no luck.
I know that's not what electron is supposed to do, if you're positively sure there is no way to do that, please tell me so I can search for another alternative.

A simple approach is to create a cluster where the master process is the Electron Main and the worker process is the server.
Example:
Change the main on package.json to start.js
On start.js write:
const cluster = require('cluster');
if (cluster.isMaster) {
require('./main.js'); // your electron main file
cluster.fork();
} else {
require('./server.js'); // your server code
}

Related

Make a logger for Node Js

I have a project in Node Js, which executes the project on port 3000 and I access from ngrok with my browser to said localhost port, and it executes a server on port 3001 to make requests to a Maria database db. The project is done in react and the server with express.
I want to save the application logs (errors, warnings, etc.) in a log file so that I can see them whenever I want.
My intention was to use winston, and while I have no problem on the server side (3001), when I try to adapt it to the main project, I get an error that it cannot save files (the reason that appears is that it runs from the browser, and you can't create such a file because you don't have access to the project folders)
Can anyone give me some advice? Am I wrong to use winston, and should I use another?
Greetings and thanks
I've never used winston before and I couldn't find anything online about your error. In the past I've always just used node's fs module to create a log of errors and restarts.
const fs = require('fs')
Node's File System Documentation: https://nodejs.dev/learn/the-nodejs-fs-module
Short YouTube Tutorial: https://www.youtube.com/watch?v=U57kU311-nE

expressJS exporting other things in addition to app

In my web application (I'm using expressJS), there are many services (such as mongoDB connection, MQTT connection, etc.) that need to be executed once the whole application is executed (using npm start command). Therefore, I can make use of these services in my entire application. For example, I want to use my MQTT connection in different files.
My idea is to export the MQTT connection, MongoDB connection, etc. in addition to the app this way:
//app.js
module.exports = {
app: app,
mqttConnection: myMQTTConnection,
db: myMongoDB
};
However, we know that this approach doesn't work (I tested it and got an error saying: TypeError: app.set is not a function).
How can I export other things in addition to app from app.js file?
If my approach is not possible, what other approaches can I use? (considering the fact that many services (such as connecting to a server, etc.) are asynchronous)

How to separate express server code from Express business logic code?

All the Node.js tutorials that I have followed have put everything in one file. It includes importing of libraries, routing, database connecting and starting of the server, by say, express.js:
var app = require('express');
app.get('/somePath', blah blah);
app.listen(...);
Now, I have 4 node servers behind an Nginx load balancer. It then becomes very difficult to have the source code updated on all the four servers.
Is there a way to keep the source code out of the server creation code in such a way that I can deploy the source code on the servers as one package? The server creation code should not know anything about routing or database connections. It should only be listening to changes in a folder and the moment a new module meta file appears, it starts hosting that web application.
Much like how we deploy a Java code packaged as war by Maven and deployed to the webapp of Tomcat, because Tomcat instantiation is not part of the source code. In node.js it seems server is also part of the source code.
For now, the packaging is not my concern. My concern is how to separate the logic and how do I point all my servers to one source code base?
Node.js or JavaScript for that matter doesn't have a concept like WAR. But what it does have is something similar. To achieve something WAR like, you would essentially bundle the code into one source file using something like webpack. However, this will probably not work with Node.js modules like http (Express uses `http since it likely calls or relies on native V8/C++ functions/libraries.
You could also use Docker and think of the Docker containers as WARs.
Here is what I figured out as a work around:
Keep the servers under a folder say, "server_clusters" and put different node servers there, namely: node1.js, node2.js, node3.js, node4.js, etc (I know, in the real world, the clusters would be different VMs or CPUs altogether but for now, I simply want to separate server creation logic from source code). These files would have this code snippet:
var constants = require('./prop');
var appBasePath = constants.APP_BASE_DIR;
var appFilePath = appBasePath + "/main";
var app = require(appFilePath);
//each server would have just different port number while everything else would remain constant
app.listen(8080, function (req, res) {
console.log("server started up");
});
Create a properties file that would have the path to the source code and export the object. That simple. This is what is used on line#1 in the above code
Create the source directory project wherever you want on the machine and just update its home directory in the constant file above. The source code directory can export one landing file that will provide the express app to the servers to start:
var express = require('express');
var app = express();
module.exports = app;
With this, there are multiple servers that are pointing to the same source code.
Hope this helps to those who are facing the same problem.
Other approaches are welcome.

Meteor file system

I have a question about meteor file structure. I´m coming from JAVA so maybe I'm thinking way too complicated.
When you create a new Meteor project (using osx shell), it creates you a folder like /usr/MyUsername/projectname/.
Inside you'll find the: project.js, project.html, project.css and the .meteor folder.
What I want to do now is:
Create a structure like: /usr/MyUsername/projectname/
There I want to create a server an a client folder. where I put the client.js and the server.js into.
Where do I set the references? For example with the following code in the project/client/client.js:
Meteor.call('somefunc', someobj);
I have in the project/server/server.js the following code:
if (Meteor.isServer) {
Meteor.startup(function () {
Meteor.methods({
'somefunc':function(someobj){
CalEvent.insert(someobj);
}
})
});
}
Where in the client.js do I tell where the server.js is? and how?
Long story short : you don't have to worry about references, as long as you put things that belong in the client under client/ and server-side stuff under server/ you're good to go.
No need to wrap your code with Meteor.isServer blocks if it lives under server/.
You don't need the Meteor.startup block either, the code you put in these sections is rerun everytime the server is restarted but you only need your method to be defined once.
The meteor tool build process takes care of merging all the client files and sends them to the browser for execution, likewise it's merging server files and spawn a Node.js process to execute the resulting bundle.

heroku: route subdirectory to a second node.js app?

I have a heroku node.js app running under the domain foo.com. I want to proxy all urls beginning with foo.com/bar/ to a second node.js process - but I want the process to be controlled within the same heroku app. Is this possible?
If not, is it possible to proxy a subdirectory to a second heroku app? I haven't been able to find much control over how to do routing outside of the web app's entry point. That is, I can easily control routing within node.js using Express for example, but that doesn't let me proxy to a different app.
My last resort is simply using a subdomain instead of a subdirectory, but I'd like to see if a subdirectory is possible first. Thanks!
Edit: I had to solve my problem using http-proxy. I have two express servers listening on different ports and then a third externally facing server that routes to either of the two depending on the url. Not ideal of course, but I couldn't get anything else to work. The wrap-app2 approach described below had some url issues that I couldn't figure out.
Just create a new express server and put a middleware in the main one to redirect to the secondary when comes a request to your desired path:
var app2 = express();
app2.use(function(req, res){
res.send('Hey, I\'m another express server');
});
app.use('/foo', app2);
I haven't tried it yet in Heroku, but it the same process and doesn't create any new TCP binding or process, so It will work. For reference, a modified plain express template.
And if you really want other express process handling the connection, you need to use cluster. Check the worker.send utility.
app.use('/foo', function(req,res){
//You can send req too if you want.
worker.send('foo', res);
});
This is possible. The most elegant way I could think is by using clustering. 1 Heroku Dyno contains four cores. Therefore, you can run four worker threads to a node process.
Here is an introduction to clustering.
What you're looking at is initializing two express apps (assuming you're using express) and serving those two in two worker threads.
if (cluster.isMaster) {
// let's make four child processes
for (var i = 0; i < 4; i++) {
if (i%2 == 0) {
cluster.fork(envForApp1);
} else {
cluster.fork(envForApp2);
}
}
} else {
// refer to NODE_ENV and see whether this should be your app1 or app2
// which should be started. This is passed from the fork() before.
app.listen(8080);
}

Resources