I have a website with game client and a server running next to the website. They communicate via sockets. The problem is that I need to have a way of setting url
for my socket depending whether the code is on server or on my local pc. When I want to debug my code and write development code I want the url to be localhost:5051 and when I push it to the server I want it to be the name of the website with specific port.
Is there any way of determining whether my code is on production or development?
I don't use webpack, I only use requirejs and I would like it to stay that way, because I need to change only one line and I don't want to use the whole framework to change one line.
Let's assume your Node file is server.js and you typically start your app by typing node server.js. When you run your app locally, instead use:
NODE_ENV='development' node server.js
Now in your app, set a var for your url.
var appUrl = (process.env.NODE_ENV === 'development') ? 'localhost:5051' : 'your-prod-url.com';
Use appUrl as needed.
You should be able to determine which environment you're on by logging socket.localAddress and .localPort, where socket is your socket's name, and setting the URL accordingly.
https://nodejs.org/api/net.html#net_socket_localaddress
Related
I'm developing a web-application with Django, which should manage and process a huge amount of user' files in local intranet. As the Django app and user files will host in the same local network, there is no necessity to upload files, it's ok to provide Django with full network path to the file via user's view.
I realised that it's impossible to get full file path from the browser due to security reasons.
There is a lot of files a user will process every day (around 150-200), so it's not ok to ask user to manually copy-paste full file path into the app. Initial design approach supposed user to drag-n-drop files from Windows Explorer to dedicated areas in the browser.
What's my options, community?
rewrite all front-end as Electron app (yikes! Just because of it!) and use Django only as REST API backend;
rewrite ducking everything as desktop app and lose all advantages Django provides (authorization, authentication, ORM, admin panel, gosh -- lots of it);
the third funny option
I feel a little stranded. Need some advice. Thanks!
I have encountered same problem while working on this.
When I think on your options
1- There is no need to re-write whole app
Create an api endpoint on server side
Create a script(program) on client that will push real paths to server
Your files should be accessible over network
Here is the script code that I used:
Tested with python Python 3.7.4 Prints realpath of all the selected files as a list.
source
import tkinter as tk
from tkinter import filedialog
import pathlib
root = tk.Tk()
root.withdraw()
root.attributes("-topmost", True)
file_path = filedialog.askopenfilenames()
# print(file_path) #debug
files = list(file_path)
print(files)
Then you need to import either a requests and generate a Json request to your server endpoint.Or just call a curl with subprocess.
2- By your definition I assume the intranet network is trusted.So is authentication necessary.And there is a question of How many users will use same file after it is processed in server.If its one then there is no need for a django app.
Well...
I've solved my problem. With much less blood than expected, which I'm happy of. :)
First, I installed Electron and one of minimal boilerplates into a new folder in my project.
In boilerplate there is a file called main.js (or index.js, depends on boilerplate), which defines Electron application window and its contents. Inside is the line which loads content to Electron BrowserWindow object:
mainWindow.loadFile(path.join(__dirname, 'index.html'));
Fortunately, BrowserWindow object does have method loadURL, which can be used to load webpage instead of local html file:
mainWindow.loadURL('http://127.0.0.1:8000');
It means that all pages rendered by Django will be shown in Electron browser, which runs node.js instead of standard browser javascript engine. Thus, this code in Django page template will work perfectly:
<h1 id="holder">DROP FILES HERE</h1>
<p id="dropped"></p>
<script>
const dropZone = document.getElementById('holder');
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
e.stopPropagation();
let filesList = '\n';
for (const f of e.dataTransfer.files) filesList += f.path + '\n';
document.getElementById('dropped').innerHTML = `Full file paths: ${filesList}`;
});
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
e.stopPropagation();
});
</script>
I'm making a discord bot with discord.js, but my reset command isn't working.
//!reload
if(command === `${botsettings.prefix}reload`) {
console.clear();
bot.destroy()
bot.login(botsettings.token);
message.channel.send("Reloaded");
return;
}
It doesn't give any error; it restarts and goes back on but the commands don't update!
I tried so many different things I found, but it doesn't work.
I only have one file for all commands.
If you use a nodemon system and a local batch file it will automatically reload the file for every change saved in it, and will output the new file changes.
If you need more help on this, watch a few videos from TheSourceCode on YouTube and you'll see in around 3-4 episodes on him using nodemon.
If you end up hosting it on Heroku, which is frowned upon, but I do, it will automatically reload for every change in your GitHub repository, just make sure to replace your token with process.env.token and make sure you have it set on your Heroku.
So i am guessing you have your various files set out (config etc) and one central bot.js file, and you load the bot by using something like
node bot.js
on your host machine, and obviously part of your .js file sets up the bot something like this:
const bot = new Discord.Client();
From what I can tell, your
bot.destroy()
and
bot.login(botsettings.token);
is just refreshing the const 'bot', but what it is not doing is reloading your bot.js file (with the updated commands and code).
What you would need to do, is have it set up to run a batch file or something on your host machine that terminates the entire process bot.js, and then restarts it. As this would then use the new and updated bot.js file.
The only problem is I am still figuring out how to run a batch file from my JS file, as understandably for security that feature isn't built in (other wise most websites that use JS would be vunerable to getting it to run things like format C:\)
I imagine it will involve using WSH in my JS, and I will update here if I do get it going.
I hope this was clear? let me know if you still have a question :)
In the code you provided, it seems like your only refreshing the const 'bot' instead of reloading the bot.js file.
I recommend that you use a batch file.
client.destroy();
client.login();
That's not possible since there's a dead socket.
Instead, you're able to make a Shell script and have a background Daemon service the needs that you want.
I'm working on an app that is going to be deploy on-prem (no cloud) and there are requirement to deploy the application to different server path. For example in one company it might be company1.com and on another it might be company2.com/app because they already have a server and want to deploy it on the same server under a different context path.
The problem is in Webpack we compile the app and create HTML+JS+CSS files. The HTML and JS files have the server context path (part after the domain name) hardcoded into the code. For example loading the JS files will be done with <script src="/hello.js" /> so if the app will be deploy to company2.com/app I need the script tag to be <script src="/app/hello.js" />
I'm looking for way to change the server context path dynamically preferably using environment variable.
For compare we use Spring on the server side and there we can define env-var server.contextPath which will change the context path in which the app works.
If it changes anything the app is deployed as docker image.
Any ideas how to implement such thing?
That's an interesting question, and there are some ways you can resolve that. I'll list some options below.
I'm looking for way to change the server context path dynamically preferribly using environment variable.
I will list some other options, but the first one is using env vars.
Using Environment Variables When Building
webpack has a plugin (DefinePlugin) that allows us to set environment variables to the javascript code.
Then, you will be able to get those environment variables using process.env. For exemple, if you have the following configuration:
plugins: [
new webpack.DefinePlugin({
fruit: JSON.stringify('orange'),
MY_VAR: JSON.stringify('value'),
API_URL: JSON.stringify('http://some-api')
})
]
Then, in your code you can get them using:
console.log(process.env.fruit); // "orange"
console.log(process.env.MY_VAR); // "value"
console.log(process.env.API_URL); // "http://some-api"
This said, you can do something like this:
Passing environment-dependent variables in webpack
Then, for example, you can just use process.env.API_URL in your code, instead of using it hardcoded.
IMPORTANT: this method will only work if you have can build your code before releasing it to production. (I think it's not a problem for you).
I think this is the best option, because your code will be "clean", it is more "customizable" and it will "simply work", regardless your environment.
Using a Map
You can have some application logic to decide your variables. For example, you may "look" to the URL (i.e. location.href) and decide the values to use based on this address.
let api;
if (domain === 'domain1.com') api = 'api1';
if (domain === 'domain2.com') api = 'api2';
Using an Extra HTTP Server
You can always point to a hardcoded path in your server, lets say /api. Then, in your code, you will point to /api. So, all your requests will go to /api.
You will need to have an HTTP Server (it can be a Nginx, a NodeJS, whatever you want) listening to /api and then have this "routing" logic there.
It will work fine, but you will need to control the deployment of this HTTP server. This may not be a good option for you, but it may suit your needs.
One advantage is that you'll be able to only change the code of this HTTP server when changing some routes, without need to deploy your front-end code again.
I think that sums it.
Hope it helps!
I'm running a Node.js server along with an Angular frontend. One of the Angular dependencies I'm using requires me to import a javascript file into my html page, by the name of swing.js. However, when I try to do this, it sends the required file as an http request to the server, resulting in requests that look like the following:
http://localhost:3000/home/me/app/node_modules/angular-swing/dist/swing.js
Obviously, this comes up as a 404. As an alternative, I've tried changing
<script src="/home/me/app/node_modules/angular-swing/dist/swing.js"></script>
into
<script src="swing.js"></script>
and then on the server-side, doing:
app.get('swing.js', function(req, res){
res.sendFile('home/me/app/node_modules/angular-swing/dist/swing.js');
});
This works a little more, but then the file doesn't run properly, as I'm assuming it's no longer in the npm environment it needs to be in. I've tried multiple iterations of changing
<script src="/home/me/app/node_modules/angular-swing/dist/swing.js"></script>
into something that uses periods (.) to represent more relative paths, but that doesn't appear to work either. Overall, I'm very stuck, and would appreciate any insight. If it's of any use, I'm also using:
app.use(express.static(__dirname+'/public'));
Making my comments into an answer...
node.js does not serve any files by default so any script files that you need sent from your server to the client upon request need an explicit route to handle them or they need some generic route that knows how to handle all the requested script files.
swing.js in the client is not part of any "NPM environment". It's running the browser at that point, not in any NPM enviornment. It's possible that swing.js itself needs some other scripts or resources that also need routes and that's why it doesn't work after you make an explicit route for it. You can probably examine the specific errors in the console to give you a clue why it isn't working.
You may also want to read this: How to include scripts located inside the node_modules folder?
I have a js file batch.js which do a batch insert for me, but I must launch it from my terminal : node batch.js. Now, I want to create a button on my frontend html page, and launch my file via the button.
You can't, per se.
You can use the browser to request a URL (and you can do it from a button by submitting a form), but you need an HTTP server listen to the request for the URL and react accordingly.
Ideally you would rewrite batch.js so it was a module and then write a webserver in Node (e.g. using Express) which would load the module and call a function exported from it when the given URL was requested (and then respond to the browser).
More hackily, you would spawn a new instance of node whenever that URL was requested and run your batch.js without modification. That would let you use any HTTP server you like and any programming language to write the server side program that would execute node batch.js.