Connection lost with response.end in node.js - javascript

I'm using node.js to have multiple clients. Now, in my code, I'm listening on a port and each time a client connects, I want to send out a broadcast message to all other clients, say. I'm raising a new event each time some new client connects, and I'm sending a response over to him. When I say response.end(), I'm not able to send anything to that specific client after that. However, the browser keeps loading and waiting for the response.end.
Is there anyway around this without using socket.io?
I know socket.io has its uses, but I really wanted to know if I can do it without socket.io.

I'd say to use two channels in your client; one to receive updates (channel kept open, or frequently querying for updates) and one to refresh the data. It involves some work on your part to restructure the client and the server, but I think using two channels is the cleanest way to solve your problem.

If you don't send the .end() the browser will keep waiting. But if you close the channel you'll not be able to send nothing through it. So, either use socket.io or open a channel via XHR and keep it open for each client to receive messages. Is up to you to adequately frame the messages (implement your applicative protocolo) though. I think Paul is right.

Try long polling, which means letting an ajax request from the browser 'hang' until the server can send something back.
How do I implement basic "Long Polling"?
Using nodejs, you could store the response objects for the clients easily.

Related

Websocket : Get information from Web socket server

I am very new to websockets and trying to create an omegle as an example. A centralized chat server to which every client can connect through a websocket and the the server matches people based on interests. The people can chat through the websocket connection thereafter.
I am just curious about one thing: Once my site goes live and different clients keep connecting, essentially in the background they are connecting to my central server through the websocket. Can't any client run javascript on its chrome console and inject a malicious script or get access to the clients connected to the server already since the connection has been established and its a stateful connection? I am not sure if there is a way to do that. And if there is, what security mechanisms i need to take care of?
The response to your question is "Yes" and "No"!
it depends on so many things. First, is your chat a public one? I mean can every body join the chat room without login?
In this case i guess everybody can chat so a guy who want to use your websockets can do so a it is public.
In the case your chat is private it is your own to protect your websockets events from being accessed by everybody. This start by registering users after a robust login process.
As all others Internet (and computer based) tech, websocket is subject to hacking. You chould protect your websockets as you protect your web based developments.
Typing "websocket common attacks" in Google will return you links that talk of websocket security.
Yes, a client can definitely inject a malicious script... but it will only affect the client's own browser.
No. There isn't a way to do that unless you explicitly created a vulnerability.
You see, first of all, websockets are not peer-to-peer connections. They require a server to transmit messages between end users, so if the server doesn't do anything about an incoming message request, the user the first user intended to send a message to would not receive anything. Essentially, this means that websocket clients can only connect to users if the server lets them.
However, even if websockets were p2p connections that would still not be possible, or what kind of a web would we have?! I hope you understand that any data sent to a client isn't automatically executed as code. It usually is in a string format and it will never be able to run any code unless you actually eval it or something. (Or you forget about XSS and don't properly escape data that would be rendered as HTML.)
So, to answer your question, no and no. Security measures? Don't eval incoming data.
However, what you do have to be aware of in websockets is that any client can connect (well, at least try) to a websocket server. See, because websockets usually are used to send data between clients, when a server receives a message, it usually will broadcast that message to everyone in that connection/room except for the sender. This means that a user with malicious intent may enter your room and send data, as well as receive data that's probably meant to be private.
To prevent this, ensure you are setting up proper authentication. You can do this through cookies, perhaps, used with session or JWT (I usually use the latter). When a user joins a room or connects, check if that user is authorized and allowed to be in the room. Otherwise, reject the connection.
Here's a bit broader explanation that might help you.
Web sockets work on TCP connections. That means the socket connects to a specific destination and transmits data ("messages"). Those messages can flow both ways (in and out). Users connect to your server using clients (most commonly a browser).
The connections are unique, meaning no two clients share the same connection. Therefore, no one else knows what others send to or receive from the server.
Messages can be of various types, but the most commonly used is a string. Typically people encode some JSON objects in those strings to perform specific actions. Something along the lines of:
{
message: "Hello!",
channel: "general"
}
Now here comes your role. How to act on those messages, and what to send to whom. Standard libraries provide functionalities like targeting a single socket or sending messages to many sockets. Imagine it like a list of connections. They can send specific commands to join/leave channels, so you add more meta data to each. In the previous example, you might want to send Hello! to every connection that has "joined" a channel (by sending a specific command to do so).
You decide what the commands are:
{
command: "join/leave",
channel: "general"
}
You might want to spread every message you receive to others or keep it to yourself (and execute some custom functionality). Nothing happens out of the box - the server receives the message, and that's it.
All of the above means that whatever users do with their clients won't affect you or others. The only way you can know of their actions is if they send you a message. Those messages you must be careful with, as they can contain any malicious code.
Therefore I'd highly recommend you use some library that deals with web sockets in case you'd like to ship something to people. If it's for learning purposes - stick to the plain functionalities.

What does it matter if there are many nodejs emitter listeners?

I'm writing a TCP server application using NodeJS. However, each socket runs on a separate child-process (server.on("connection")). To send messages to specific clients, I used Emitter, and each socket generates its own listener (on clientID). So if there are 10000 connected devices, the application will create 10000 listeners. This looks terrible. What dangers will this pose? I can't find a solution to send a message from one client to another in the TCP protocol writing NodeJS code.
Update:
Have any idea to send message to specific client without add custom listeners?
However, each socket runs on a separate process.
Why would you do that? The core idea behind NodeJS is to run things in an event loop. Single threaded, yes, but asynchronous.
This looks terrible. What dangers will this pose?
It is terrible. The biggest issue is that you sacrifice a lot of resources. You not only spawn thousands of processes but you also spawn lots of emitters. So first of all this means lots of RAM eaten. Secondly this means degraded performance due to process context switch, which typically is slower than user space switch. Assuming your machine will even allow you to spawn so many processes.
I can't find a solution to send a message from one client to another in the TCP protocol writing NodeJS code.
I assume you have a TCP server, two connected clients and client A wants to send message to client B. Is that correct? TCP by itself won't do that for you. You need some protocol on top of it. For example:
Client connects to the server. At this point the client is not logged in and cannot do anything except for authentication.
Client authenticates. It sends (username, password) pair to the server. The server validates the pair. The server keeps a global mapping {"<username>": [sockets]} and adds newly authenticated client to that mapping.
Client A wants to send a message to client B. So it sends data of the form {"type": "direct", "destination": "clientB", "data": "hello B"}. The server parses the message and forwards it to the appropriate client (taken from the global mapping).
In case when you want to broadcast the message you send say {"type":"broadcast", "data": "hello all"} kind of message. The server then parses it, it loops through all connected clients (found in the global mapping) and forwards the message to each client.
Of course you also need some framing of packets. Since TCP is a stream, then it doesn't really understand messages and where one starts and the other ends. Dumping things to JSON is a half of the problem. Because then you have to send this JSON over the network and the other side has to know how many bytes it has to read. One way is to prefix each message with, say, 2 bytes that tell the other side how long the message is.
Btw you may want to consider using socket.io (or some other lib) that take care of some of those tedious details for you.

instant messenger communicate using http rather than tcp/websocket

I notice an instant messenger using javascript/http/xmlhttprequest rather than tcp/websocket to communicate.
such as http://w.qq.com/login.html
I monitored its communication way in chrome developer tool.
All are http requests. One request to server every minute.
The thing I confused is that if I send a message to the http client, it receives the message immediately.
As I know http client can not get message from others, it has to send request and get response.
Is there any way to make http client to get message from others without using tcp/socket or sending request and geting response?
Your comment welcome
I don't get all this asian hieroglyphs, but they probably use long-polling: client asks server for new data and server holds answer (don't send anything, and don't close connection) while data is not ready (new message came) or until huge timeout expired. As soon as connection closed, client process response and sends next long poll request. The more common term for "permanent" connect via http called Comet. As you can see, Comet can be implemented via many techniques. As for me, the most modern is ajax streaming. It requires modern browser of course, but worth it. It's not so hard to implement streaming by yourself, but I believe there are few js libs which do the job for you.
Upd:
Here is pretty good explanation with code source
and
here is one of many questions about streaming on SO (the answer in the bottom is most interesting I guess)

callback javascript

I write a browser game (php, javascript) and I do not know how to make a callback. necessary that the server itself
found a client and call the function (only had one)
Don't write a browsergame if you don't know the basics! Browsergames are way too complex to learn programming.
If you want to make the server notify a client about something you will need to keep a connection open (search keywords: COMET, long polling) as you cannot initiate connections from the server to clients.
For this I can suggest you using Firebase. It is a API that let you to add cloud Data management that your user clients do. You can use that communication to search for client.
If I understand your question, what you need is a socket. Since you're using PHP and Javascript, a WebSocket might be just what you're looking for. With WebSockets, the connection between the client and the server is persisted, so the server can just push data/messages to any or all of the clients connected to it at any point in time. Likewise, the any client connected to the server can push messages/data up to the server.
Here's a video that describes how it works a bit https://www.youtube.com/watch?v=oJxWhmt5m-o

Javascript to socket server conneciton

I wanted to create a web chat. It was suggested that i use Php Socket Servers. I've made one and they function well with a telnet client.
What i find myself bamboozled by is how to get that data to the client via ajax (no page refreshes).
All I can come up with is calling a php file with ajax, getting the data and updating the page. But that will not work the other way around.
Or am i missing something?
How would you implement a 1 on 1 web chat?
One solution is long-polling. The client will open up an AJAX request to a script that will block and wait for data to come in. If no data comes in within a minute, it will return and the client will reopen the connection. If data comes in, then it will immediately return the data and the client will update its view.
For sending the data, just do a normal AJAX callback.
You've got the idea of client-initiated communication, which is fine for sending things from the client to the server.
As a consequence of the stateless nature of HTTP, there is no way to "push" data, unbidden, to the client.
The way you get around this is by always leaving a connection back to the server open. The request is pending, and when the server has something to say, it responds to the pending request. Whenever this happens, the client creates a new request to leave sitting until the next time server->client communication must happen.
Another way to implement near-real-time communication is through frequent polling. But I don't recommend this approach, really. Especially not for a chat program.

Categories

Resources