Designing Real Time Web Application - javascript

We have a real time application where AppServer( written in c/c++) used to broadcast network event details
(typically few hundred to around thousand rows with around 40-50 columns per second) to Client GUI app written in gtk
over network using XML/RPC, as well as writing to DB(running on same machine or LAN). 95% communication is from server to client.
It was working fine with no issues.
We have to port the application to web. In initial attempt we kept C/C++ app server as it is. Now we are sending the data to java web
application server through xml/rpc. Java server keeps a circular queue (initially kept small size of 2000) and pushes data
to client through websockets. At client we are using angular ui-grid to display the data.
Currently the problem is browser can not handle this amount of data at this frequency and
after some time (few hours) become unresponsive. This is a network monitoring app supposed to be run 24/7 and though we have very few
users, we don't have much control over their machine's configuration (mostly low/medium end). Server (tomacat 8) was running on 2*6 core, 16 GB RAM.
Can you give suggestions for improving browser performance? We are even ready to implement new solution from scratch.
But I think browser performance will be always the bottlneck.

if the pushed data is persisted somewhere else, you should implement a worker to clean the browser data periodically.
For an example say you have been pushing 1000 records per minute, and the browser crashes around one hour period, you could implement a worker where every half an hour, it cleans the browser DOM in order to keep the memory footprint at its lowest.
To access previous data, you should have an API implemented where a user could fetch data for a given time/data period.
it's hard to identify what is causing the crashes, but IMO it should be a heavy DOM which the browser is unable to handle after a certain time. It's better if you could provide an details report of the browser when it crashed.

Related

What are some good use cases for Server Sent Events

I discovered SSE (Server Sent Events) pretty late, but I can't seem to figure out some use cases for it, so that it would be more efficient than using setInterval() and ajax.
I guess, if we'd have to update the data multiple times per second then having one single connection created would produce less overhead. But, except this case, when would one really choose SSE?
I was thinking of this scenario:
A new user comment from the website is added in the database
Server periodically queries DB for changes. If it finds new comment, send notification to client with SSE
Also, this SSE question came into my mind after having to do a simple "live" website change (when someone posts a comment, notify everybody who is on the site). Is there really another way of doing this without periodically querying the database?
Nowadays web technologies are used to implmement all sort of applications, including those which need to fetch constant updates from the server.
As an example, imagine to have a graph in your web page which displays real time data. Your page must refresh the graph any time there is new data to display.
Before Server Sent Events the only way to obtain new data from the server was to perform a new request every time.
Polling
As you pointed out in the question, one way to look for updates is to use setInterval() and an ajax request. With this technique, our client will perform a request once every X seconds, no matter if there is new data or not. This technique is known as polling.
Events
Server Sent Events on the contrary are asynchronous. The server itself will notify to the client when there is new data available.
In the scenario of your example, you would implement SSE such in a way that the server sends an event immediately after adding the new comment, and not by polling the DB.
Comparison
Now the question may be when is it advisable to use polling vs SSE. Aside from compatibility issues (not all browsers support SSE, although there are some polyfills which essentially emulate SSE via polling), you should focus on the frequency and regularity of the updates.
If you are uncertain about the frequency of the updates (how often new data should be available), SSE may be the solution because they avoid all the extra requests that polling would perform.
However, it is wrong to say in general that SSE produce less overhead than polling. That is because SSE requires an open TCP connection to work. This essentially means that some resources on the server (e.g. a worker and a network socket) are allocated to one client until the connection is over. With polling instead, after the request is answered the connection may be reset.
Therefore, I would not recommend to use SSE if the average number of connected clients is high, because this could create some overhead on the server.
In general, I advice to use SSE only if your application requires real time updates. As real life example, I developed a data acquisition software in the past and had to provide a web interface for it. In this case, a lot of graphs were updated every time a new data point was collected. That was a good fit for SSE because the number of connected clients was low (essentially, only one), the user interface should update in real-time, and the server was not flooded with requests as it would be with polling.
Many applications do not require real time updates, and thus it is perfectly acceptable to display the updates with some delay. In this case, polling with a long interval may be viable.

How to make a network architecture without the server being authoritative

As a prototype i'm making a multiplayer paint game on a canvas using javascript and websockets. The conditions are that the server cannot generate the canvas in any way. All model logic happens on the client-side.
Right now i have the following setup:
1) When an input happens on the client side it is transferred to the server and saved. The server does a very simple validation check.
2) Every 15 ms (on the server) all inputs are sent to the clients and cleared. The clients render the input locally.
3) Every 200 ms each client send their version of canvas to the server where it is saved
4) Every 200 ms the server votes for the "right" version and send it backs to the clients where they update their canvas. The right version is stored on the server with a timestamp.
5) When a new client connects they get the most recent right version of the canvas from the server.
While this approach provides multiplayer paint with a persistent state, it also carries some issues. What is the right version and how do they vote? What happens when a client experience a lag for like 10 seconds and then send their version? Also, if each client is making constant local changes, the canvas for each client will never be quite the same, making it impossible? to find the correct version of the canvas because they all differ when sent to the server.
The question can be boiled down to: It is possible to make a reliant client-server architecture where the client does all the logic and the server only checks if the input is valid? Even if it entails more network traffic. And if so, what would be a good approch?
Upon further investigation I found some excellent documentation on the above problem.
Having a client-only network model can be described as a peer-exchange model and was actually what was used in age of empires 1+2. However, as Microsoft faced several issues getting the clients to run synchroniously (and small variations broke the game), I have decided on a server model instead with some shortcuts to actually enable the server to merge the models.

web socket connection closed when behind proxy

I've a web sockets based chat application (HTML5).
Browser opens a socket connection to a java based web sockets server over wss.
When browser connects to server directly (without any proxy) everything works well.
But when the browser is behind an enterprise proxy, browser socket connection closes automatically after approx 2 minutes of no-activity.
Browser console shows "Socket closed".
In my test environment I have a Squid-Dansguardian proxy server.
IMP: this behaviour is not observed if the browser is connected without any proxy.
To keep some activity going, I embedded a simple jquery script which will make an http GET request to another server every 60 sec. But it did not help. I still get "socket closed" in my browser console after about 2 minutes of no action.
Any help or pointers are welcome.
Thanks
This seems to me to be a feature, not a bug.
In production applications there is an issue related with what is known as "half-open" sockets - see this great blog post about it.
It happens that connections are lost abruptly, causing the TCP/IP connection to drop without informing the other party to the connection. This can happen for many different reasons - wifi signals or cellular signals are lost, routers crash, modems disconnect, batteries die, power outages...
The only way to detect if the socket is actually open is to try and send data... BUT, your proxy might not be able to safely send data without interfering with your application's logic*.
After two minutes, your Proxy assume that the connection was lost and closes the socket on it's end to save resources and allow new connections to be established.
If your proxy didn't take this precaution, on a long enough timeline all your available resources would be taken by dropped connections that would never close, preventing access to your application.
Two minutes is a lot. On Heroku they set the proxy for 50 seconds (more reasonable). For Http connections, these timeouts are often much shorter.
The best option for you is to keep sending websocket data within the 2 minute timeframe.
The Websocket protocol resolves this issue by implementing an internal ping mechanism - use it. These pings should be sent by the server and the browser responds to them with a pong directly (without involving the javascript application).
The Javascript API (at least on the browser) doesn't let you send ping frames (it's a security thing I guess, that prevents people from using browsers for DoS attacks).
A common practice by some developers (which I think to be misconstructed) is to implement a JSON ping message that is either ignored by the server or results in a JSON pong.
Since you are using Java on the server, you have access to the Ping mechanism and I suggest you implement it.
I would also recommend (if you have control of the Proxy) that you lower the timeout to a more reasonable 50 seconds limit.
* The situation during production is actually even worse...
Because there is a long chain of intermediaries (home router/modem, NAT, ISP, Gateways, Routers, Load Balancers, Proxies...) it's very likely that your application can send data successfully because it's still "connected" to one of the intermediaries.
This should start a chain reaction that will only reach the application after a while, and again ONLY if it attempts to send data.
This is why Ping frames expect Pong frames to be returned (meaning the chain of connection is intact.
P.S.
You should probably also complain about the Java application not closing the connection after a certain timeout. During production, this oversight might force you to restart your server every so often or experience a DoS situation (all available file handles will be used for the inactive old connections and you won't have room for new connections).
check the squid.conf for a request_timeout value. You can change this via the request_timeout. This will affect more than just web sockets. For instance, in an environment I frequently work in, a perl script is hit to generate various configurations. Execution can take upwards of 5-10 minutes to complete. The timeout value on both our httpd and the squid server had to be raised to compensate for this.
Also, look at the connect_timeout value as well. That's defaulted to one minute..

LibGDX GWT - WebSocket Causing Temporary FPS Spikes

BACKGROUND:
I'm implementing a client that communicates to a server using a WebSocket. The core of the client application is built ontop of LibGDX and it is deployed solely in browser form using GWT (HTML5/JavaScript). This is for a side-project - a fast-paced (high network traffic), online, browser-based game.
Without providing any source - essentially the client code is an empty LibGDX application that provides a correct implementation of gwt-websockets (a commonly recommended GWT wrapper for JavaScript websockets).
SYMPTOMS OF THE PROBLEM:
(pre-note: This appears to be a purely client-side issue) I start the application and connect to the server. On 1000 ms intervals the client application sends a packet to the server and receives a packet back - no problems. There are also no problems when I send and/or receive two, three, or even five packets per second.
Speeding up that process faster however ... approximately sending more than 10 packets per second (100 ms intervals) from the client to the server OR receiving more than 10 packets per second (100 ms intervals) OR both sending and receiving 10 packets per second (100 ms intervals) causes the client to slowly drop in FPS while the packets are pouring in, out, or both. The more network communication, the lower the FPS floor becomes (slowly drains from 60...55..50..45..all the way down to 1 if you keep sending the packets). Meanwhile, the server is completely healthy.
Here's the weird thing which makes me suspect there is some sort of buffer overflow on the client - after a packet has been "handled" (note: my Websocket.onHandle() method is empty), the FPS jumps back up to ~60 as if nothing ever happened. From this point, if a packet is sent or received, the FPS drops right back down to the floor value (except a tad bit worse each time this occurs).
FURTHER DEBUGGING:
I've looked into the possibility of memory leaks on my end, but after
going through a 15 hour debugging session I doubt my code is at fault
here (not to mention it is essentially empty). My network class that
communicates via Websocket contains literally a bare-bones
implementation and the symptoms only occur upon network activity.
I've read about potential garbage collection causing undesirable
performance hits in a GWT deployment. I don't know much about this
other than I cannot rule it out.
I doubt this matters but my server uses Java-WebSocket to
communicate with the client's gwt-websocket
MY BEST GUESS:
I'm really stumped here. My leading suspicion is that there exists some sort of bug in gwt-websockets with buffers and the handling of frequent network traffic or possibly there is a memory leak.

Real-Time with Node.js: WebSocket + Server-Side Polling vs. Client-Side Polling

I'm developing application that displays real-time data (charts, etc.) from Redis. Updated data comes to Redis very quickly (milliseconds). So it would make sense to show updates as often as possible (as long as human eye can notice it).
Technology stack:
Node.js as a web server
Redis that holds the data
JavaScript/HTML (AngularJS) as a client
Right now I have client-side polling (GET requests to Node.js server every second that queries Redis for updates).
Is there advantage of doing server-side polling instead, and exposing updates through WebSocket? Every WebSocket connection will require separate Node.js poll (setInterval) though since client queries may be different. But it's not expected to have more than 100 WebSocket connections.
Any pros/cons between these two approaches?
If I understood your question correctly: you have less than 100 users who are going to use your resource simultaneously, and you want to find out what can be a better way to give them updates:
clients ask for updates through time-out request (1 per second)
server keep track of clients and whenever there is an update, it issues them an update.
I think the best solution depends on the data that you have and how important is for users to get this data.
I would go with client-side if:
people do not care if their data is a little bit stale
there would be approximately more then 1 update during this 1 second
I do not have time to modify the code
I would go with server-side if:
it is important to have up to date data and users can not tolerate lags
updates are not so often (if for example we have updates only once per minute, only 1 in 60 client side request would be useful. And here server will just issue only one update)
One good thing is that node.js already has an excellent socket.io library for this purpose.

Categories

Resources