How use app.use in io.on? - node.js

How I can use app.use in socket.io? E.g.
io.on('connection', function(data){
app.use('uri here', function(req, res){
// emitting here
});
});
It's really?
I have:
ss1.example.com (head-server for caching online users with users servers).
ss2.example.com (first app server)
ss3.example.com (second app server)

You're misunderstanding something here. The sequence of events when a web page is loaded is as follows:
User initiates page load (by clicking on something or by typing something in the URL bar or by selecting a bookmark).
Browser parses the server, gets the host and port out of the URL and sends an http GET request for the path to the IP address for that host and port.
Web server receives the GET request and sends back to the browser an HTML page.
The web server may or may not use middleware when that request is received (depending upon what it wants to do).
Browser parses the HTML page and then runs scripts in the page.
Javascript in the web page runs and initiates socket.io connection to some host (often to the same host that the web page came from).
Web server receives socket.io request and socket.io handle recognizes the web request as a socket.io connection request.
Server-side socket.io code responds to client request for socket.io connection and a socket.io connection is initiated between browser and server.
Client or server can then send data over the socket.io connection.
Now, to your question about where to insert app.use(). That is for http middleware. You would insert that in the regular web server request chain, typically right before you app.get() and app.post() request handlers. You would not typically use http middleware for a socket.io connection.
If you wish to run some code before any socket.io connection connects, then you would use io.use() and use a socket.io middleware handler. That will give you access to the http request information on every socket.io connection request.
If you wish to run some code on every socket.io message that is received (regardless of the message name), that is not a supported feature of socket.io. There are some add-ons that hack into socket.io to allow you to essentially do a socket.on('*', ...) type event handler for all incoming socket.io messages, but that is not something that socket.io supports as a built-in feature.
If one of these options still doesn't sound like what you want, then please explain to use what actual problem you're trying to solve and we can better make a suggestion for that particular problem.
Note your question is a bit like an XY problem where you asked how to do what you think is the solution (using app.use() for socket.io) rather than describing the actual problem you want to solve. The problem with that type of question is that if you're wrong about the solution direction, then all we can really tell you is that you're wrong with that solution because you didn't describe the actual problem so we can direct you to the right type of solution. In the future, you will probably get better answers if you make sure to describe the problem you're trying to solve, not just the solution you're trying.

Related

Is socket.io data emitted from server protected?

So I'm just learning socket.io and I think I know just enough to be dangerous. I've built a test (Node/Express) application that first takes you to a login page, then redirects you to an account page, after authenticating. The account page view is on a protected route, and it listens for a particular event emitted from the server and then displays that data in the browser. My question is if the data is being emitted from the server, can't it be listened for outside of the protected /account route and then viewed if someone knows the name of the event? If so, rendering the account view on a protected route is useless and I need to figure out how to authenticate a user before allowing the server to emit the data...right?
To clarify, my setup is as follows:
From server.js -
io.on('connection', (socket) => {
console.log('New user connected...');
socket.emit('data', {
//data emitted
});
});
From account.js (one of the js source scripts for my account.hbs view) -
socket.on('data', function (data) {
//do some stuff with the data
});
You haven't really disclosed enough for us to offer you info on your exact scenario so I'll generally describe how this works and what you do and don't need to worry about.
If you run your socket.io connection using TLS, then all data is protected in transit and cannot be snooped on by a middleman attack. If your socket.io connection is not TLS, then data is visible to network snoopers.
It is not enough to protect only the /account route form which a socket.io connection is made. You also have to protect the socket.io connection itself. Otherwise, any code jockey can write up a script that will make a socket.io connection to your server and you will happily let it connect and send it data. You need authentication on the socket.io connection itself. socket.io offers middleware support for that and if you already have an authenticated session for the /account page, then you can implement middleware that requires that authenticated session before allowing the socket.io connection. Then, you will have auth support for socket.io connections.
My question is if the data is being emitted from the server, can't it be listened for outside of the protected /account route and then viewed if someone knows the name of the event?
If your socket.io connection is not running an encrypted channel such as TLS, then it can be snooped on. Someone doesn't have to know the name of the event (it can be seen other ways) and it would be relatively easy to figure out the message name by just looking at the client JS in your web page.
If so, rendering the account view on a protected route is useless and I need to figure out how to authenticate a user before allowing the server to emit the data...right?
I wouldn't say useless, but it's not sufficient to provide protection for the socket.io connection. That connection needs it's own auth implementation which can likely piggyback on the same auth you did for the /account page.
Summary: Run socket.io on TLS (support https on your server and use an https://xxxx URL to connect for socket.io) and then implement authentication for your socket.io connections.

Creating a socket to a website to retrieve that pages information

How would I create a socket to a site to retrieve that pages information? If I'm using meteor do I have to do an HTTP.get in a loop(it's a multiplayer game so things are constantly changing) or is there a way to actually create a socket to the site. I looked at Socket.io but I was only able to find how to listen and accept, not actually create a socket to a site.
EDIT: In my case http://play.pokemonshowdown.com/ . I'm assuming if I keep doing http.get requests, it'll won't save the state and thus keep creating a new game. Could I somehow create a socket between my site/server to their site/server till I disconnect? Basically, whatever a browser does but I don't want to display that information but rather redirect it to another socket(not part of the question).
The answer here depends upon what the site you want to connect to supports. If it is just a web server that creates web pages, then your only option is to use an HTTP get operation to request a web page.
If the site supports a specific API, you can make an HTTP get operation to a specific API request and get a more structured response than just a web page.
If the site supports webSocket or socket.io connections with specific request/response messages defined, then you can connect with either a webSocket or socket.io.
But, it all depends upon what the receiving site supports.
If you are trying to do repeated requests from node.js, you would likely not use a loop, but more like a timer such as:
setInterval(function() {
request.get(..., function(err, response, body) {
// process error or response here
});
}, 10* 1000);
It may also be the case that the request module is of use to you since it adds a lot of functionality on top of the http module when trying to retrieve requests from an HTTP server.

Differentiate between client connections with node?

I need to implement a server that can handle simultaneous connections from both a client app and a browser that share a common database, however the clients from the browser have different functions from the clients of the app. I would like suggestions if this is the best design implementation. I decided not to have a different server for the client app or from the browser for this same reason as I can foreshadow synchronization issues when retrieving/writing information form the database. Is there a way to somehow attach a string or other information in front of the http connection to be able to tell each apart?
when the connection is made to the server what should be done?
var server = http.createServer(function(request,response)
{
//Code to tell them apart
});
Your client app is the best place to start. Do you have control over the client app? If you can modify it to send a specific header, that may work. Otherwise, another way to do so is to differentiate between User Agents... If the client app will always have a specific UA, treat all requests with that UA as a client app request, and all others as a browser request.

Pure socket logic

I have a nodejs app, and every client has an open socket connection, the reason i am using sockets because I need to update the data on the client whenever the data in the database changes by an external process.
However every other operation in my app doesn't require a socket connection and mostly initiated by the client (CRUD operations), But i am confused about one thing since I always have an open socket connection, wouldn't it be better to use that socket connection for every operation and make the app with pure socket logic?
When using websockets maybe it's fine. But if socket.io switches to XHR (AJAX) transport it might be irrational.
Take a look at the differencies of these two approaches:
In case of simple AJAX (without socket.io) when you want to get some info from server, or change something on a server, you send GET or POST request,
and server responses. Everything's fine.
But in case of socket.io (XHR transport) there is one request to send data, and another to get the response.
(You can make your own experiment - write io.set('transports', ['xhr-polling']); and try to send data to the server and make server respond -
you will see 2 AJAX requests in the Network tab)
So instead of one AJAX request socket.io makes two requests.
This is not because socket.io is bad. This is a feature of sockets approach. This approach is good if you want one side (client or server) to send messages independenly from the other. This is what socket.io does very good.
But if you want to do "request-response" stuff it's the best to use simple AJAX because of traffic economy (note that I compare simple AJAX to socket.io AJAX. Websockets - is another story).
But since this question is about approaches and can't have 100% "yes" or "no" answer, there are might be different opinions.
Sorry for English. I tried to write as clearly as I could :)

Should I be using socket.io for my nodejs application?

I am learning HTML5 and doing so by building a simple chatroom using Express, PassportJS, Mongoose/MongoDB, connect-mongoose, NowJS.
Everything works perfectly, except for one big problem: I am having trouble authenticating NowJS.
The usual way of doing this is to read the "this.user.cookie" property server-side and parse the string. However, for some reason, cookies is not being sent back to the server. (details here: NowJS cookie field in this.user is empty) After a lot of googling, I think there are no alternative, secured, way for me to authenticate NowJS connections/clients.
Question
I am thinking of stripping all of NowJS out of my web app, and using socket.io directly. Is socket.io easy with work with? Would I lose key functionality if I switch to socket.io, instead of using NowJS?
Can I use socket.io to:
1) Call server-side functions?
2) Share server-side variables with the client?
Socket.io does not share variables or allow you to call server side functions. It allows you to bind and emit events on the client side and server side.
As for your cookie not being sent, its most likely that its being considered a cors, cross domain request, this can happen if your using a different port for socket.io then the http server that set the cookie.

Resources