I need to refresh a part of my view without refreshing the whole page.
At my index.html page I have three panels, wich one shows the number of Tickets by it's status, I need to refresh this number every time a new ticket is created or updated. I used Java with Spring Boot and Thymelaf to build my application.
This is my view:
This is the way I'm doing it now:
model.addAttribute("resolvedTickets", atendimentoService.findAllTicketsByStatus(STATUS_RESOLVED).size());
I have tried to use web sockets but i can't figure out how to get this and refresh the panels.
In a standard web interaction, the client (i.e. your web browser) sends a request to your server. Your server receives the request, and sends back the information to show in your browser and then terminates the connection.
WebSockets are a way to create a persistent, two-way connection between the client and the server, but it requires cooperation from both. A lot of shared servers don't allow WebSockets, so you first have to make sure your server is capable of providing WebSockets. (I see from your screenshot that you're running on Heroku, which should have no problem running WebSockets.)
On the server side, you need to set up handling for incoming WebSocket requests. I don't know what language you've coded your server in, so I can't provide any guidance, but there are plenty of libraries that do the server-side part of WebSockets in most languages.
On the client side, you need to set up your WebSocket client. MDN has a great guide on WebSockets that explains what you'll need to do. Basically, all you'll have to do is listen for incoming messages and increment your counter.
var count = 0;
var exampleSocket = new WebSocket("ws://example.com/socket");
exampleSocket.onmessage = function(event) {
count++;
document.getElementById('myTicketCounter').innerHTML = count;
}
For some things, WebSockets are overkill. If you find that this is too much work for too little reward, you can also just set up an AJAX call to fire every few minutes that pings another page on your server and returns the number of tickets and updates accordingly. It won't be instantaneous, but if you don't need down-to-the-second resolution, it'll probably suffice. You can adjust the interval to be as long or as short as you want (to an extent; bombarding your server with constant requests will slow you down a bit).
Related
I've seen how to make a post request from JavaScript to get data from the server, but how would I do this flipped. I want to trigger a function in the flask server that will then dynamically update the variable on the JavaScript side to display. Is there a way of doing this in a efficient manner that does not involve a periodic iteration. I'm using an api and I only want to the api to be called once to update.
There are three basic options for you:
Polling - With this method, you would periodically send a request to the server (maybe every 5 seconds for example) and ask for an update. The upside is that it is easy to implement. The downside is that many requests will be unnecessary. It sounds like this isn't a great option for you.
Long Polling - This method means you would open a request up with the server and leave the request open for a long period of time. When the server gets new information it will send a response and close the request - after which the client will immediately open up a new "long poll" request. This eliminates some of the unnecessary requests with regular polling, but it is a bit of a hack as HTTP was meant for a reasonably short request response cycle. Some PaaS providers only allow a 30 second window for this to occur for example.
Web Sockets - This is somewhat harder to setup, but ultimately is the best solution for real time server to client (and vice versa) communication. A socket connection is opened between the server and client and data is passed back and forth whenever either party would like to do so. Javascript has full web socket support now and Flask has some extensions that can help you get this working. There are even great third party managed solutions like Pusher.com that can give you a working concept very quickly.
Basically I'm working on an application that posts huge amounts of data to web API(third party API).
I am working on nodejs to connect to MsSQL server and fetch data, process it and post it in desired format to the web API.
Scenario is: In nodejs, I have script that does the above job. It is currently initiated (or should I say triggered?) by a button on web page using axios POST with all necessary parameters. Eg below:
axios.post('/api/v1/fetch-new-labors', {
startDate: 'somedate',
endDate: 'someDate'
}).then(...handles further processing & posting to api)
The process takes around 2-3 mins to finish. Meanwhile, if the page is refreshed, it obviously needs to restart the whole process by clicking the button.
Question: I am sure there is a way to let the process run(on serverside I presume) that takes care of fetching, processing and posting even if the client side page is refreshed/reloaded and at the same time, keep the client side informed with progressbar or x out of y records posted kind of thing. I thought of web sockets but I wasn't sure if there's a prefered way to achieve this. I'm not looking for the whole code/process, I am looking for someone to guide me towards overall concept/idea.
tl;dr: Long-running jobs usually avoid using the traditional request-response cycle, opting instead for some variation of the Pub/Sub pattern described below:
Accept request, then start processing
You should respond to the user immediately with an HTTP 202: Accepted, signalling you accepted the request, then start the processing.
You can perform some initial checks before responding (Does the user have other jobs? Does the request pass basic validation checks?) but you should not start processing the actual long-running job before responding.
You can use a simple HTTP request to create jobs.
Push status updates from server to subscribed clients
On page load the client subscribes to updates from the server.
Using WebSockets, push server-to-client status notifications regarding the progress. Don't forget to also handle and display errors to the client.
At this point, you'll probably need a way to uniquely identify each client across refreshes. You can easily solve this by storing a UUID via LocalStorage when a user first visits your app/website. If your app requires logins, then you can use the logged-in user's ID instead.
Check if user has already running jobs before accepting a new one
When the user refreshes you can send an initial message via WebSockets again notifying the user if he has any running jobs and what their progress is.
Based on your OP, I think you might want to disable the "Create Job" button if there's a pending job.
You can use other mechanisms for bidirectional server-client communication (such as long-polling/Server-sent Events) if you want, although WebSockets should be the most straightforward and flexible solution.
I'd personally go for a batteries-included WebSocket library such as socket.io.
I have a 3rd party service to implement, that provides restful API with long polling... they are serving live events, and displaying it as quick as possible is crucial.
Sadly that service does not provide push notifications, so we need to deal with what we have....
so one of the APIs has a long-polling functionality, so in theory the idea is, I query the API, establish an open channel for 30 seconds and wait for the changes... (and publish the changes on the FE)... and then timeout the connection, establish a new one and repeat the process.
Should be pretty straight forward....
But so far, I couldn't find anything in angular's docs about long polling... the only thing I found was polling in connection with rxJS... so setting an inteval on how often I query the API... (which in my case would be every 30s)... but nothing about on leaving the channel open and listen for the changes...
found this thred:
How to implement http long polling in Angular 2
but it is not talking about this problem.
I don't want to end up querying the API every second.
Any ideas?
I considered implementing signalR (which might not really help here), but it relies on jQuery... which I don't want to add to the bundle unless is 100% necessary!
I think you misunderstood the concept of long-pulling..
Long-pulling where the client polls the server requesting new information. The server holds the request open until new data is available. Once available, the server responds and sends the new information. When the client receives the new information, it immediately sends another request, and the operation is repeated. This effectively emulates a server push feature.
It you want to keep the connection alive you need to use webSoket.
WebSockets provide a persistent connection between a client and server that both parties can use to start sending data at any time. The client establishes a WebSocket connection through a process known as the WebSocket handshake. This process starts with the client sending a regular HTTP request to the server
But I didn't understood from your question why you can't send another fetch request when the long-pulling completes, something like:
myLongPullingFunc(){
this.http.get(longPullingURL)
.subscribe(res=>{
if(sholdFetchData){
useFetchedData(res);
this.myLongPullingFunc();
}else
doSomethingElse()
})
}
You can read more about long-pulling here and on webSokects here
I am kind of new to JavaScript / jQuery and Web Development. My current project is to build a small chat room for a website. Everything works, but I have one question:
How to transmit date from the client to the server and back (e.g. via javascript) (e.g. when some chat member sends a message)?
Of course I have implemented a solution that works: I use $.get(...) or $(...).load(...) to transmit data. Of course, every query is listed in the network section of the browser inspector. But when you open the inspector on 'big' sites, e.g. Facebook, no network activity is listed although I am sending/liking/clicking, which all has to be send to the server and be processed.
So how the hack do these sites transmit data??
Another problem: How does the client receive information from the server (e.g. if some other chat member has send a new message)? Currently I run a time interval that checks every 2 seconds for new messages.
It is going to be a big refactoring, but you should read https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
I have X amount of activity sensors connected to a server that inserts data to a database everytime a sensor is triggered. What I'm trying to do is create a web interface with a blue print of the facility (svg) and whenever a sensor is triggered, besides the db insert, I want it to show some sort of alert in my blue print. For that I need to keep an open connection to the server I think.
I was thinking of using web sockets, but it might be overkill since I only need to retrieve data from the server. But running an ajax call every second doesn't sound very efficient either. Are there any other alternatives?
Thank you
Some potential choices include:
WebSocket
Adobe® Flash® Socket
AJAX long polling
AJAX multipart streaming
Forever Iframe
JSONP Polling
Which actual transport you end up using will depend on the your requirements for browser support and what technology you are using on the server to handle these requests. The transport choice may also depend on your network topology - what types of load balancers you need to integrate with, proxies, etc.
There are many libraries available on both the client and server sides, many of which support more than one of these transports.
For example (not an exhaustive list):
socket.io for nodejs
WebSocket
Adobe® Flash® Socket
AJAX long polling
AJAX multipart streaming
Forever Iframe
JSONP Polling
SignalR for an asp/.net backend
WebSockets
Server-Sent Events
ForeverFrame
Long Polling
Atmosphere for a java backend
WebSockets
Server Side Events (SSE)
Long-Polling
Forever frame
JSONP
IMO - Websockets is NOT overkill for this type of problem and would lend itself nicely to this type of application.
Without specifically discussing frameworks or knowing what is running in the backend of your server(s), we have a few options to consider for the frontend:
Websockets
Websockets are designed for bidirectional communication, although it is kind of shocking how many users are surfing the web in a browser that doesn't support websockets. I always recommend a fallback for this, such as the other methods listed below.
SSE
SSE is an HTML5 spec and is still shaky at best. Try scrolling on a page while when an SSE event fires... It may be a little easier on the backend, put it sometimes hangs on the client side since it runs inside the same thread that the DOM is running in.
Long Polling
Keeps your connection open. It doesn't scale well with PHP, but performs swimmingly with Python+Twisted on the backend, or Node.Js
Good Old Ajax
Keep your requests small, and you still have a scalable solution. Yes, a full GET request is the most expensive, but is supported in just about every browser rolled out the past ten years. It is also worth noting that GET requests are easy to scale horizontally with more hardware.
In a perfect world:
You would break up your application into a few components, operating behind a reverse proxy such as Nginx. Then use Node.Js + Socket.IO handle the realtime aspects of your app.
Another option would be to use small Ajax requests, and offer websocket support for the browsers that support it. This is advice specifically for PHP in the backend.
WebSocket is certainly not overkill. On the contrary. With websockets, you have a bi-directional communication channel; this means, that the server can initiate communication whenever it seems fit (e.g. when sensor data changes).
In a previous project, I have used node.js together with socket.io, to monitor 50+ sensors. Data was updated in real-time in a browser. The data was visualized using smoothie.js.
Whenever a sensor value was updated, it was communicated to the browser. Some sensors only updated once a minute, others once a second, ...
Polling would have been overkill, because it would retrieve all data for all sensors, even from those that were not updated yet.
I had a similar problem and did a lot of research on this. As I understand it, there are three main options:
Short polling: Have an endpoint that your javascript client pings every second. This is the worst option, because the pings add latency up to one second to your communication, and depending on how you implement, the endpoint could query the database every second, adding unnecessary overhead.
Long polling: Have an endpoint that your javascript client pings that holds the connection until a) the event occurs or b) the connection times out. If the endpoint returns a response, the client gets the event information. If the endpoint does not return a response, no event has occurred, and the client sends a new request. This is a good option because the events can immediately trigger the response to the client, assuming you have an asynchronous interprocess communication layer (like 0MQ) to send the message without any sort of polling.
Websocket: Have your javascript client connect to a websocket server, which will send a message to your client immediately upon the event trigger.
I think a websocket is your best option, because it accommodates immediate communication of the event without all the request/response overhead. And most importantly, this is exactly what websockets are designed to do! As such, you will probably have to write the least amount of custom code with this solution.
There are two great commercial services that might work for you.
Firebase - a javascript hierarchical database and realtime
messaging/ synchronization platform, uses websockets and has other fallbacks
PubNub - a real time message passing and queue system, uses websockets