Connect to a remote socket.io server from Django server - javascript

I am trying to build a real-time Django application.
Because of the way my hosting service works, I am unable to start a Websocket server in parallel of my Django server.
I managed to have user-to-user interactions by creating an express server on a separate NodeJS website with socket.io, and having clients on the Django server also connect to the remote socket.io server.
However, I'dlike to have my Django server directly send events to users. To do this, I would like to create a connection between the Django server and the NodeJS server. Something like that in python:
socket = io("http://socket.io.server")
socket.emit('eventForUsers')
Is there anyway for me to achieve this?
The only information I found seemed to require me to run a parallel server from my Django app, which I can't do because my host doesn't allow me to run long-term processes.

It really depends what is the most simple solution for you, and what are your requirements. (If you want realtime bidirectional messaging then I suggest to use the socket.io-client instead of the POST example)
POST (GET,PUT,...)
You can (for example) use POST requests from your Django to Node
Django: python example (there are other ways to perform a POST to Node from Django)
reqParams = {"action":"doThis","data":"put the pizza in the oven"}
import requests
requests.post('http://ip:port/route', params = reqParams)
Node example : Listens for post at /route (express) and prints the params of the Django request
var express = require('express');
var app = express();
app.post('/route', function (req, res) {
console.log(req.query); res.end();
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Then you can use the data in req.params to perform action like broadcasting something to the socket.io clients (or a specific client)
This can also be done the other way around, performing requests to send data from Node to Django using POST (GET,...)
Socket.io-client in Django
Another (easier) solution is to include the socket.io-client in your Django webapp so it connects to your Node socket.io server as a client when the webapp is opened by browsers.
(using javascript in django)
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://ip:port');
socket.on('connect', function(){alert("Hello World!");});
socket.on('event', function(data){});
socket.on('disconnect', function(){});
</script>
More Resources :
1. JavaScript (Django Docs)
2. Including the static files in your template

Related

NodeJs: How do I access the functions of my JavaScript backend from my HTML frontend?

Here is my HTML code in index.html.
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="stuff()">Click</button>
<script>
async function stuff() {
await connectToServer();
}
async function connectToServer() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
alert(this.responseText);
};
xhttp.open('GET', 'C:/Users/myName/myFolder/index.js', true);
xhttp.send();
return;
}
</script>
</body>
</html>
Then, here is my backend code in index.js.
const express = require('express');
const axios = require('axios');
const port = process.env.PORT || 8080;
const app = express();
app.get('/', (req, res) => {
res.sendFile('C:/Users/myName/myFolder/views/index.html');
});
app.listen(port, () => console.log(`Listening on port ${port}`));
I can type node index.js on the command line and run this program and go to http://localhost:8080/ . When I do this, the html page shows up as intended. However, when I click the button in order to make a GET request to the server side, I get a console error saying Not allowed to load local resource: file:///C:/Users/myName/myFolder/index.js . I'm using Google Chrome by the way.
I know that it is a security thing, and that you are supposed to make requests to files that are on a web server (they begin with http or https). I suppose then, my question is:
How do I make it so that my server file index.js can be viewed as being on a server so that I can call functions on the backend from my frontend?
You have to make an HTTP request to a URL provided by the server.
The only URL your server provides is http://localhost:8080/ (because you are running an HTTP server on localhost, have configured it to run on port 8080, and have app.get('/', ...) providing the only path.
If you want to support other URLs, then register them in a similar way and write a route to handle them.
The express documentation will probably be useful.
You should not need to load your server-side code into the browser. It's server-side code. It runs on the server. It isn't client-side code. It doesn't run in the browser. The browser does not need access to it.
If you want to load some actual client-side JS from the server, then use <script src="url/to/js"></script> (and not Ajax) and configure express' static middleware.
Let's improve your current flow by separating your backend API process from frontend hosting process. While backend can, it's not good in serving static html files (especially for local development purposes).
Run your backend as usual, node index.js. But as soon as this command will become more complicated, you will probably want to use npm scripts and do just npm start)
Run separate server process for frontend. Check out parcel, snowpack, DevServer. It can be as easy as npx parcel index.html, but this command is likely to change frequently with your understanding of your tool features.
To call backend, just add an API endpoint to an express app (just like you already did for serving static content), and call it, using backend process URL.
Usually, you will see your app on http://localhost/ and it should do requests to http://localhost:8080/.
If for some strange reason you will want to dynamically download js file from your server to execute it, you just need to serve this file from your frontend hosting process. In order to do so, different development servers have different techniques, but usually you just specify file extensions and paths you want to be available.
After editing frontend files, you will see hot-reload in browser. You can achieve the same for node process with various tools (start googling from nodemon)
If you find this way of operating not ideal, try to improve it, and check what people already did in this direction. For example, you can run two processes in parallel with concurrently.

Sending data from client javascript file to server javascript file (node.js or other) and getting the response back

TL;DR:
How can I send data from client-side javascript to server-side javascript file (node.js or whatever), receive it there (and do some stuff with it), then send it back to client-side javascript file for further usage?
Full description of the issue
There is an HTML page with a form, from which myjavascript.js collect user input and process it on client side (using FormData). Then myjavascript.js sends the processed input to myphp.php (server-side) this way:
myjavascript.js:
ajax = new XMLHttpRequest();
ajax.open("POST", "../../myphp.php",false);
ajax.send(formdata);
return ajax.responseText;
The data (formdata) is then received by myphp.php, undergoes some further processing, and then is sent back to the myjavascript.js:..
myphp.php:
$fieldOne = $_POST["fieldOne"];
$fieldTwo = $_POST["fieldTwo"];
...
($fieldOne, $fieldTwo etc. are processed, and the result is assigned to $results)
...
echo json_encode($results);
exit();
... where it is returned by return ajax.responseText; (as in myjavascript.js code above). And then this data is displayed on the HTML page etc.
The question
I used to do this way before. Now I would like to use server-side javascript (say, myserver.js) instead of myphp.php. I have the code for processing the data in myserver.js, I just do not understand how to receive the data from myjavascript.js and send the response back. Is it possible, and if yes, how the code for it should look like? Generally, I do not quite understand how the mechanism of receiving POST data in server-side javascript (and sending the response back) differs from the PHP one. Thank you for any suggestions and comments.
In PHP, the web server portion is typically implemented by some other framework, and your PHP scripts are called by that framework. For example, an Apache module may call your blah.php script incoming web request is for /blah.php. This means PHP developers often think in terms of the browser calling a PHP file, but it's actually more complicated than that behind the scenes.
A typical Node.js setup, in contrast, is that the JavaScript code itself implements the web server listener. You run node with your server JS script, and that script starts the server. The built-in http module, for example, lets you implement an low-level HTTP listener through createServer:
const { createServer } = require('http');
const { once } = require('events');
const server = createServer(async (req, res) => {
const chunks = [];
req.on('data', chunk => chunks.push(chunk));
await once(req, 'end');
const body = JSON.parse(chunks.join(''));
// Do stuff with the body
res.statusCode = 200;
res.end('Success!');
});
server.listen(8080);
console.log('Server is listening at http://0.0.0.0:8080/');
So basically, stop thinking in terms of a client-side JavaScript file sending things to a server-side JavaScript file and think in terms of your browser sending an HTTP request to your HTTP server.
I'd recommend you use a framework instead like express or koa to build your server since it lets you more easily configure route-specific handling for requests, and they have the ability to use pre-built "middlewares" to do the common stuff like JSON body parsing and much more.
You need to use node js and express js so that you can reach your goal easily.
Run the following commands after installed node js:
$ npm install express --save
$ npm install body-parser --save
myserver.js
const express = require('express')
const app = express()
const port = 3000
const bodyParser = require('body-parser')
app.use( bodyParser.json() )
app.use(bodyParser.urlencoded({
extended: true
}))
app.get('/', function (req, res) {
console.log(req.body.fieldOne)
console.log(req.body.fieldTwo)
res.send('Hello World!')
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
And then, run your server with the bellow command:
$ node myserver.js

Communication with an http-server

I have some data that I want to store locally and to be able to pull it dynamically, maybe in another session or after the browser was closed and all browser data was cleared.
I run the site with http-server CLI command and navigate to localhost to access it from the browser.
How can I send data to the server side so the server side will save the data as a file?
I tried to do an ajax post request to see if something happens in the console, but it just returned 404 and nothing came up in the console.
The docs don't mention anything about post requests: https://www.npmjs.com/package/http-server
PS: I have to run this with http-server, this is an offline project.
You will not be able to do this with http-server alone, because http-server can only serve static content and cannot be used to run any code on the server side.
You will have to write a backend yourself, possibly using a framework like Express, Hapi, Restify, Loopback etc. and serve your static files that you need with your new backend, or keep it served as you do now but then you will probably need to take CORS into account if you use different ports for your data saving/retrieving endpoints and your static content - unless you run a reverse proxy that makes it all appear on the same host name and port.
You can use the file system to save the data or you can use a database - either a standalone database like Mongo or Postgres or an embedded database like SQLite or Loki.
For examples on how to serve static content in your own backend see:
How to serve an image using nodejs
You should use express for this kind of stuff. You can easily make methods that handle certain requests.
Here is an exmaple on how to handle a get request by just sending some data
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World')
})
app.listen(3000)
And you can use the fs api from node itself to write data.
var fs = require('fs')
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
if (err) throw err;
console.log('It\'s saved!');
});
Note: the fs example uses arrow functions. You can find more information here

What the best way to deploy javascript based web app?

I'm a j2ee developer and till now I've deployed web apps in Tomcat, Weblogic and many App Servers, which were completely j2ee based.
Now I'm developing a Javascript based app that uses require js for module, QuickBlox and Firebase JS.
Now what are my options to deploy them so that a user can use them for chatting purpose like via www.chatapp.com
We are using Amazon's cloud platform EC2(I'm new to it).
From my experience, NodeJS is the way to go if your application will be a Single-page application. NodeJS will give you the ability to manipulate your application on the fly in the server side with pure JavaScript if necessary.
To start with, you can use ExpressJS to serve your files. From ExpressJS documentation:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
})
The app starts a server and listens on port 3000 for connections.
Read the ExpressJS docs for more information. There is a lot of ways to serve files in NodeJS. You can search for more in npmjs.com
If you are using Firebase as your backend, and just need to serve your HTML/CSS/JS files to clients, you could simply place those files in an S3 bucket and enable static website hosting.

How to make Node.js listen to specific website and use AWS?

So I'm kind of new to Node.js but i really want to host a website that uses Node.js in the background using Amazon Web Services (AWS). I am using Socket.io and Express.js with Node, and i have a html file with the client side code.
Here's part of each file:
server.js:
var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
io.on("connection", function(socket) {
console.log("-- User Connected");
});
//express home page
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
//express listen on 8080
http.listen(8080, function() {
console.log("Running...\nListening on port 8080");
});
index.html (Just the client-side javascript)
<script src = "/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
var socket = io.connect();
socket.on("connect", function() {
console.log("connected");
});
});
</script>
Everything works great, but i was wondering how i would upload this to a AWS bucket and run it there. I already uploaded the full .html file to a AWS bucket and set up the host, so it opens and runs fine. But how would i go about uploading and running the server.js file? and what would i change in both the client side code (change io.connect() parameters?) and the server.js code (change .listen() to something?) so it runs with AWS?
Any help is much appreciated, thank you!
Buckets are a feature of AWS' simple storage. They only support static files. You can't use them run server side side programs that you wrote yourself.
For that you'll need a different product, such as EC2.
You can run Linux on Amazon EC2 instance.
Guide to get started with Amazon EC2.
Step 1: Create a Github/Bitbucket repository of your project so it can be easily cloned on the server. Private repo in GitHub are paid while in Bitbucket it's free under some conditions.
Step 2: SSH into the server. Clone the project. Install the required packages. Now you can run the node server on EC2 instance as you do on your localhost.
Step 3: AWS provides you with public DNS something like: ec2-**-**-**-**.compute-1.amazonaws.com Now access node server through ec2-52-86-163-5.compute-1.amazonaws.com:3000/
Step 4: To run the node app continuously you need something like forever
You can only use S3 for hosting static websites as described in this example.
If you would like to host your Node.js application on AWS I recommend that you use Elastic Beanstalk as explained in Deploying Node.js Applications to AWS Elastic Beanstalk. The main difference compared to hosting the Node.js application on EC2 is that Beanstalk is a service that provides a runtime environment, i.e. you do not have to set up and manage the operatings system yourself. All you need to do is to package your application and upload it to Beanstalk. Consequently, a launch environment will be created and configured with the AWS resources needed to run your code.
For more information, please read What Is AWS Elastic Beanstalk?

Categories

Resources