jquery/angular scheduler implementation - java

I have a chat application written on jquery. When user sends a message, this message is being sent to java REST endpoint. But I also want to listen for response. I think it would be good to listen other REST endpoint every second, because I have no idea how to implement it like in Facebook. So if there new message, get them and show. How to do that in jquery?

There are couple of solutions for that, but I'd suggest you do not create chat application using REST. If you want pure JS think about firebase from google (it will be realtime)/meteor or definitely using Websockets (you'll need a websocket server and you can use authobahnjs to subscribe to that server).
I do realize it's solution that's more complicated than REST, but if you ask me and probably your customers REST is really not the best choice for chat/realtime applications...
Just think of situation where you will have lots of users online and each of them will not only be sending a lot of queries (if they write fast) but as well checking for response every second. Now think if something goes wrong on the network what will happen with your server... you'll get tons of 'hanging' connections etc.
btw. ppl who tried it (like me in past) will tell you the same, no chats with polling for messages over REST! ;)
JQuery way...
Ok, just watch out for defining multiple events on the same element (that’s classic one when working with Jquery), here’s a function that should do what you want (its a post, but you can adapt it):
var interval = 1000; // 1000 = 1 second, 3000 = 3 seconds
function doAjax() {
$.ajax({
type: 'POST',
url: 'chatController.php',
data: {action: 'getMessagesForUser', user: {user: 'data'}},
dataType: 'json',
success: function (data) {
//do something with results
},
complete: function (data) {
// Schedule the next
setTimeout(doAjax, interval);
}
});
}
setTimeout(doAjax, interval);
You could also introduce some variable that would make sure you're not making another request before the previous one has completed etc.

Related

Stream ajax/xhr content into page while loading

Is there a way to "stream" content into a page while the XHR/AJAX call is loading? I have setup a REST based Java servlet (Restlet), using JSP for templating, and am using JavaScript to generate all the content via Dojo XHR calls to the RESTlet. The downside to this is while I'm waiting for page elements to finish loading asynchronously, they do not display. Not a problem locally, but when SSH'd in even 60 KB can take a bit of time to dynamically load if I'm in a bad 3G area, less some JSON fetches are 1-6 MB in size.
And yes I realize JSON has no order guarantee.
I would like to render the content as it's downloaded, instead of waiting for the content to complete the asynchronous fetch and then call function to render it after the xhr request "on load".
Example:
function getFinanceData() {
aniPreload("on");
var thePostData = "doWhat=getFinanceData";
var xhArgs = {
preventCache: true,
url: getResource("Finance"),
postData: thePostData,
handleAs: "json",
timeout: timeOutMilli,
load: function (data) {
putAssets(
data.qMerged[0],
data.bGames,
data.books,
data.dTools,
data.licenses,
data.assets
);
naviButtonListener();
aniPreload("off");
},
error: function (data, iostatus) {
aniPreload("off");
window.alert("xhrGet for FinanceData FAIL!, STATUS: " + iostatus.xhr.status + " (" + data + ")");
}
};
dojo.xhrPost(xhArgs);
}
Instead of load: function(data) { } I would like something like while loading function stream.
Your question is a bit jumbled, but... If 60K is taking a noticeable amount of time, you will have to live with that. For big transfers, where you want to see the beginning of the transfer while the rest completes, break the big request into smaller ones.
Update: I didn't mention this before, because would involve a lot of refactoring. But, I believe you could use WebSocket to achieve the streaming aspect. I didn't mention it before, however, because I'm not sure how streaming a long JSON is going to really help...

504 Gateway timeout while generating excel file

I'm trying to implement excel export for some amount of data. After 5 minutes I receive a 504 Gateway timeout. In the backend the process continues with its work.
For the whole service to finish, I need approximately 15 minutes. Is there anything I can do to prevent this? I dont have access to the servers in production.
The app is Spring boot with Oracle database. I'm using POI for this export.
One common way to handle these kinds of problems is to have the first request start the process in the background, and when the file has been generated, download the results from another place. The first request finishes immediately, and the user can then check another view to see if the file has been generated, and download the results.
You can export the data in smaller chunks. Run a test with say 10K records, make a note of the id of the last record and repeat the export starting at the next record. If 10K finishes quickly, then try 50K. If you have a timer that might come in handy. Good luck.
I had the same situation where the timeout of the network calls wasn't in our hand, so I guess you have something where it is 5 mins to receive the 1st byte and then the timeout is gone.
My solution was, let's assume you have a controller and a query layer to talk to the database. In this case, you make your process in the Async way. The call to this controller should just trigger that async execution and return the success status immediately, without waiting. Here execution will happen in the background. Futures can be used here as they are async and you can also handle the result once completed by using callback methods of Future.
You can implement using Future and callback methods in java8 like below:
Futures.addCallback(
exportData,
new FutureCallback<String>() {
public void onSuccess(String message) {
System.out.println(message);
}
public void onFailure(Throwable thrown) {
thrown.getCause();
}
},
service)
and in Scala like:
val result = Future {
exportData(data)
}
result.onComplete {
case Success(message) => println(s"Got the callback result:
$message")
case Failure(e) => e.printStackTrace
}

HTML 5 Websocket and Java_Websocket by TooAllNate

I got a big problem with using the HTML5 websocket in combination with "java_websocket" by TooAllNate.
I use the standard functions of HTML5 websocket, but especially the onmessage() function makes me cry. My current problem is, that i only get message from the server directly after load the page, that means, if the page is running, for example for 2 min, and isnt reloaded, i cant receive any new messages.
var ws = new WebSocket("ws://localhost:8887");
ws.onmessage = function(evt)
{
alert(evt.data);
}
Is anyone there, who got the same Problem or can help me?
Best Regards

Asynchronous SSE Listener in Java Servlet

I am new here so forgive me if I am not familiar with standard operating procedure, but I have researched this topic at length and haven't found a lot of info.
I am trying to implement a client in a Java Http Servlet that can subscribe to a server-sent-event stream and parse data from that stream. Every time I have a client POST a request to my Http servlet, I need to pass on some data from that client to another server and then open an SSE listener, as that is how the other server will notify me it has data for me to hand back to the client.
It needs to be asynchronous and probably multi-threaded because I will have many requests from the client happening in a short time frame and I need to catch every event coming back from the server. The data I pass back from the server to the client can be large so I need threading so I don't miss new events coming in.
I am at a loss for where to start. I have tried implementing some of the example code using the Jersey SSE API (https://jersey.java.net/documentation/latest/sse.html) but when I implement their asynchronous SSE event handling example, the events coming in happen too fast for my handler to process all the data back to the client and the function gets called again from a new event before it finishes, or at least that's what seems to be happening.
Here is a synopsis of what I have written so far:
Client client = ClientBuilder.newBuilder().register(SseFeature.class).build();
WebTarget target = client.target("Target URL");
EventSource eventSource = new EventSource(target) {
#Override
public void onEvent(InboundEvent inboundEvent){
if ("in".equals(inboundEvent.getName())) {
//Check if the event is of the type we care about
//If it is, open an input stream to read the payload and store in a byte array via an HttpURLConnection object
//Open an output stream and stream the payload to a client via an HttpServletResponse Object - This never seems to happen
}
}
};
}
I know it's sloppy, I'm not as familiar with Java so I am just piecing things together so I apologize for that.
This gets called from within my servlet class but it never makes it to the point where I write to the output stream, I think because it's getting interrupted by another event coming in. If anyone has insight into how I can make this work, or another way to do it, I would greatly appreciate it. Thanks.
I recommend you the JEaSSE library (Java Easy Server-Sent Events): http://mvnrepository.com/artifact/info.macias/jeasse
You can find some usage examples here:
https://github.com/mariomac/jeasse

Spring MVC, best practice how to often polling server

Im working on web application using the following stack of technologies: Spring, Hibernate, JSP. I have a task to make one of user social element - messages. As standard of implementation message system i take facebook system. On of the problem i faced is a polling server every 1-5 seconds (what period i have to take?) to retrieve an information about unread messages. Also i want to polling server to retrieve new messages at conversation page (like a chat). What i did:
Example code of get count unread messages.
Server side:
#RequestMapping(value = "/getCountUserUnreadMessages", method = RequestMethod.POST)
public #ResponseBody Callable<Integer> getCountUserUnreadMessages(#ActiveUser final SmartUserDetails smartUserDetails) {
// TODO add additional security checks using username and active user
return new Callable<Integer>() {
#Override
public Integer call() throws Exception {
Integer countUserUnreadMessages = messageService.findCountUserUnreadMessages(smartUserDetails.getSmartUser());
while (countUserUnreadMessages == 0) {
Thread.sleep(1000);
countUserUnreadMessages = messageService.findCountUserUnreadMessages(smartUserDetails.getSmartUser());
}
return countUserUnreadMessages;
}
};
}
Client side:
(function poll(){
setTimeout(function () {
$.ajax({
type: "post",
url: "/messages/getCountUserUnreadMessages",
cache: false,
success: function (response) {
$("#countUnreadMessages").text(response);
}, dataType: "json", complete: poll, timeout: 1000 });
}, 3000);
})();
So client send a request to retrieve count unread messages every second with a timeout in 3 seconds (is it good decision?).
But i think that is the worst callable code ever :-P
Tell me how to do better? What technique use?
Additional information:
Yeah, i supposed that it would be highload, many users service in the Internet.
Try Spring 4 WebSocket support:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
WebSockets support full duplex communication over a dedicated TCP connection that you establish over HTTP.
If you are expecting this application to have to scale at all I would make that timing interval more like every 30 - 90 seconds. Otherwise you are basically going to be designing your own built in DOS attack on your self.
You might look into Spring Sockets. It sounds like it's long polling option might work better for you.

Categories

Resources