Notification in javascript - similar to new emails in gmail - javascript

I am creating a widget which will update some live NEWS happening. I want to push notification to the widget everytime I get some new information in my database. It is similar to live feed. I am unsure how to start this one in javascript.
I donot want to poll every nth second to get the information. I want the server to push information to the client everytime the server gets a new information.
It is similar to gmail. You get an email even without refreshing the page.
Any pointers will be definitely helpful.

You basically have 2 choices, what I can think of:
Using HTTP, you can ask the server every x second, if it has any new information, and if it does, then load & show it. If you are using HTTP, the server can't contact the client, it can only answer the clients requests.
Using sockets, you can create a 2 way communication, both the client can send data to the server, and the server can send data to the client. This way the server can send the information as soon, as possible. Here you can find information about the supported browsers.

Intermediate Node server can help to separate the business logic from polling operations.
Needs to install these packages - socket.io, express, request
npm install <package_names>
To get request data from node :
var socket = io.connect('http://localhost:3000');
socket.emit('pollNodeServer',JSON.stringify(requestToServer));
On server :
var http = require('http'),
request = require('request'),
app = require('express')(),
server = require('http').Server(app),
io = require('socket.io')(server);
server.listen(3000);
console.log('Server started at port 3000');
var options = {
headers : {
'Content-Type' : 'application/json',
'User-Agent' : 'request'
}
};
socket.on('pollNodeServer', function(data, callbackfn) {
requestServer(data,socket,callbackfn);
});
Reply from server :
socket.emit('returnJobs',JSON.parse(body));

Related

Is it dangerous to establish WebSocket connection in a js file?

So, basically, I have this code :
let socket = new WebSocket('ws://localhost:8080/server.php');
socket.onopen = () => {
console.log('connection established !');
}
I use this code to establish a connection for a Real-Time Quiz. But after going to the Sources page of my inspector, I can see the whole javascript code in my browser, including ws://localhost:8080/server.php. Is it dangerous to show it (unintentionally) ? If someones creates a script and puts in it the same url (not localhost, it's just an example), can he receive/send data to the server ?
yes,it is dangerous. u can:
verify the client http request header for example 'Origin'. make sure the client website is the right client website.
use a TSL websocket service, visit to the server over SSL. So the protocol is changing to: wss://
give the client a request token, put this token in header or in post data, the server verify this token.
check the request times of a client in limited time. make sure a specific client won't request too frequently

Connect client socket to a cookie

I am making a chat program.
I am using an Nginx server and NodeJS.
I have setup a websocket via ssl and that works fine.
I have decided to use cookies for authentication.
There are two functions which are crucial:
mconnection.prototype.make_server_https=function(){
console.log('Make server https');
var cthis=this;
var server_https=modules.https.createServer({
key: this.ssl_key,
cert:this.ssl_cert,
ca:this.ssl_ca
},(request,response)=>{
console.log('### CreateServer ###');
console.log('CreateServer, Request:');
console.log(request);
console.log('CreateServer, Response:');
console.log(response);
console.log('######');
and
mconnection.prototype.make_server_websocket=function(){
var server_websocket=new modules.ws.Server({server:this.server_https});
var cookie = require("cookie");
var cthis=this;
//whenever a new client connects with the server.
server_websocket.on('connection', function(client_socket, request){
console.log('### On Connection ###');
console.log('OnConnection, Client Socket:');
console.log(client_socket);
console.log('OnConnection, Request:');
console.log(request);
console.log('######');
If I do state the port number in the client url,function make_server_https gets run and inside there i can access the cookie and set it via the response object.
but in the original url,function make_server_websocket gets run, and there i have access to the client_socket on the server. But there it seems i dont have access to the cookies.
I need to client_websocket to start the connection with this given client. And I need to tie it somehow with the cookies login information.
But i never have both at the same time so i dont get how i could connect them to make the login happen.
I am probably misunderstanding something, any help in the right direction would really be appreciated.
you have to serve you index page from node server using GET then when the request reaches backend you will have response object which can then be used to SET-COOKIE if not set from backend.
And after GET request is complete COOKIE will be added in browser, when next request is made for websocket connection COOKIE will be added to the request in REQUEST HEADERS by the browser which will be available in backend through request object.
And if you decide to use it in login system then you can SET-COOKIE on successfull login.
i got it. its an event called on headers, not on connection. and there i can just push onto the headers.

how to send code to node server from js file?

I'm trying to do google authentication in my website, where the user gets authenticated on a page. After authentication, it generates a code which contains access_token and refresh_token, and I want to send it to my Node server.
I know Xhttp is a way but I want to avoid that.
So I tried using handle bars. But they only work for html right?
Is there anyway I could use something like helpers to send my code to the server?
I tried to get around some posts like:
How can I share code between Node.js and the browser? (which is quite old, Node must've evolved till then right ?)
Sending data from javascript/html page to Express NodeJS server (I didn't understand this one honestly)
I'm new to Node.js so any guesses or any reference to the docs?
One standard way is setting access token and refresh token on Cookie, so it will be sent with every http request to the backend and can be extracted on server side (node), for example if you use express:
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
this will set req.cookies with an object keyed by the cookie names.
Another option is to use http Authorization header to send the tokens.

Keep Node JS connection opened and write (GET Request)

I was trying to implement a NODE JS get method where I could encode in the url parameters and send back responses like in Server Sent Events.
For example, when I used:
curl -D- 'http://localhost:8030/update'
The server would return a message, and then keep the connection opened to return more messages (like Push).
I was using require('connect'), I tried with require('express') but can't get it working.
Here's part of my code:
var http = require('http');
var connect = require('express');
var app = connect();
app.use(bodyParser.urlencoded({ extended: false }))
.use(bodyParser.json()) // JSON
.use(cors(corsOpts))
.get('/update', updateMiddleware);
var server = http.createServer(app);
server.listen("twserver.alunos.dcc.fc.up.pt", 8030);
function updateMiddleware(req, res) {
res.setHeader('Connection', 'keep-alive');
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.writeHead(200);
setTimeout(function() {
res.write("this is an event");
res.flushHeaders();
}, 1000);
setTimeout(function() {
res.write("this is another event");
}, 2000);
// should print without ending
}
EDIT: I found it was working, but only in chrome. In terminal, I only receive it after waiting a long time, and messages come like in chunks.
You can't use a single HTTP request to listen for multiple event data. If you are really stuck with HTTP (i.e. WebSocket or WebRTC is not an option) then the technique you are looking for is called long polling. This basically works this way:
Client sends request to server
Server waits until an event happens (or until a specific but not too long timeout, so the client application does not throw a timeout error for the request)
Server responses with a complete http response, containing the details of the event
Client receives the event details and immediately sends another request to listen to further events.
This method really takes advantage of HTTP Keep-Alive
EDIT:
For me it looks like your code does not follow the protocol of server sent events. Here is a tutorial: Server-Sent Events in nodejs.
Following another tutorial on MDN about Server-Sent Events, the structure of the messages should be the following:
: this is a test stream
data: some text
data: another message
data: with two lines
Note that the data to be sent must be followed by a double new-line \n\n.
In general, http endpoints in Express aren't supposed to do things like that. If you want live event data, the best way is to use a web socket.
That being said, this thread has an example on how to force Express to do this.
socket.io or Webrtc is the best choice

NodeJS and web sockets: Check if socket origin is the same as the web socket server

Edit: I'm sending data from app A to app B over web socket, where A is a router app for something else, and B is my web app. When B receives the data, it should send it to any client viewing its home page, also over web socket. But, since the roter app and the home page clients are connected to the same web socket server, I don't know which connections are to the clients viewing the home page, and which connections are to other stuff, like my router. Only the home page clients should receive the data.
I basically want to pass the logging data recieved from my router to my home page in real time so I can view it.
========
I have an express app that server a simple html page. It runs this script:
var host = window.document.location.host.replace(/:.*/, '');
var ws = new WebSocket('ws://' + host + ':5000');
ws.onmessage = function (event) {
console.log(JSON.parse(event.data));
};
In the nodejs backend, I have a simple ws server running, listening for connections:
var WebSocketServer = require("ws").Server;
module.exports.init = function(server) {
var wss = new WebSocketServer({ server: server });
wss.on('connection', function (ws) {
...
});
};
I get connections from, at the moment, 2 different locations.
A router app I have running that is sending this web app logging messages.
The html-page that this web app is serving.
I want to pipe the data from the router app to my html page, but to do that I need to know which of my connections I need to pipe the data to. I can in theory have many connection, but only one of them, at least for now, should be passed the data after it is recieved.
I thought I could compare the origin of the web socket connection to the domain of the web server the web socket server ran on.
I can get the origin of the connection like this: ws.upgradeReq.headers.origin. That will return e.g: localhost:5000. But I don't know the domain name where my web socket server is running. I've tried to google, and it seems like to get the domain name, I need to get it from an http request. What I am looking for is something that just gives me the name, without having to wait for an http request.
I've tried os.hostname(), but it doesn't give me the results I need.
I've also tried server.address(), where server is var server = require("http").createServer(app);, but that gives me this: { address: '::', family: 'IPv6', port: 5000 }.
Isn't there just a way to get the host and port? Can I somehow use the address part above to get the host name?
The web app will probably run on Heroku.
Based on your recent comments, it sounds like each browser client that connects a webSocket should just tell your server what web page it is looking at with an initial message and the server should keep track of that for each active connection.
In socket.io (built on top of webSockets), you could just connect to the /homepage namespace and then that server could broadcast to all sockets connected to that namespace. You could, of course, implement that type of functionality yourself with a plain webSocket.
Then, your server would not only have a list of connected sockets, but could also know what page they were all from. That would allow you to broadcast based on current page. Your server-to-server webSocket would not have sent a message that it's from the home page, so it would not be tagged as such and you could avoid sending to it.
You might find socket.io easier to use for all of this. In additon to namespaces on both client and server, it also gives you automatic reconnection from browsers, a simpler message passing system, server-side broadcast to namsepaces and so on.

Categories