I have a client written using Strophe that is loaded on every page on my website. To minimize latency I save the rid, the jid and the sid at each page change so that I can use Strophe's attach() method.
However, I am unsure of if the pausing and attaching keeps me in the MUC. If it does, is there a patch to the Strophe MUC plugin that lets me set handlers without rejoining the MUC?
Yes, you do. BOSH pause and attach leaves your stream open, the XMPP server does not even know it happened (since it happens at the BOSH layer).
Pausing is just a graceful way of telling the BOSH connection manager not to expect requests from you for a short period of time. In BOSH it is not necessary to keep a HTTP request open at all times to keep the XMPP stream alive, only that you make requests often enough for the connection manager to be satisfied that you have not gone offline without warning.
Related
My Flutter mobile app communicates with my back-end server. The docs say it's better to use Client class (IOClient) than plain get, put, etc. methods to maintain persistent connections across multiple requests to the same server.
Docs also say that:
It's important to close each client when it's done being used; failing
to do so can cause the Dart process to hang.
I don't understand when I need to close the client, because almost all app screens require HTTP connection to the same server. What's the best practice here?
Update:
Is it OK to close Client only before app is terminated, or should I close it every time app is hidden (goes to paused state)?
I personnaly think that closing client after each user action is the best practise.
What i call an "user action" can be constituted of multiple API request.
So i think the best is something like that:
var client = http.Client();
try {
var response = await client.post(
Uri.https('my-api-site.com', 'users/add'),
body: {'firstname': 'Alain', 'Lastname': 'Deseine'});
var Response = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
...
// Add here every API request that you need to complete the users action
} finally {
// Then finally destroy the client.
client.close();
}
Don't close the HTTP Client
For some of you, it may sound odd, but the solution is as simple as not to do that.
Why
In most cases, the HTTP Client should be available for the whole app run time. Also, app resources are disposed automatically when the app is closed by the user. For that reason, in most cases, we don't need to handle the disposal of the HTTP Client.
When to dispose an HTTP Client?
Only if we want to run a limited, one-time, predicted, season of HTTP requests. In that case, you can dispose of the Client in many different ways (depending on your state management or the lifecycle that you want to trigger the disposal).
The dispose() function is common to all packages that handle cache and local resources. The documentation mentions that option, but it does not suggest you use it in every scenario. It should be handled in very specific scenarios only.
So for most of you, just don't dispose of the HTTP Client.
Keep connections atomic per server interaction.
almost all app screens require HTTP connection to the same server
One thing is that all screens make http calls, other thing is having constant high frequency interactions with the server.
Let's say we have a multiplayer app, that requires each second that passes to communicate with the server. If that was the case, leaving the client open would be critical. Even though you have the architectural consequence that the dart process would hang. This would mean that dart may not be the best solution for a high server traffic app.
To my understanding your app is not the case. You don't need to worry about leaving the connection open constantly, so you could only open and close it each time you need to use it without having to pay a high performance price.
It should be seemless to the user if you are opening a connection each time you try to consume your API.
Having said this, here are some other insights on this topic:
A large amount of clients connected to the server, even when not active, may consume resources of memory or objects (for example, if there is one thread per connection). On the other hand, keeping the connection on, will allow the client to detect if there is a connection problem to the server much faster (if that even matters). Extracted from this other thread
Hopefully this will help you, given your use case, take a better decision.
In terms of network traffic, it's better to use the same client throughout the app lifecycle. Establishing a new connection for each api is very expensive. However, as per the documentation,
It's important to close each client when it's done being used; failing to do so can cause the Dart process to hang.
Also, if client.close() isn't called, it doesn't mean that the server will keep the connection open forever. The server will close the connection if it is idle for a period more than the HTTP Keep-Alive Timeout. In this case, if the client sends a new request over the connection closed by server, he'll get a 408 Request Timeout.
So, if you decide to use the same client throughout the app lifecycle, keep in your mind the two possible issues that you may run into.
I am building an OSX app that needs to get data from server. The easy way, is to make a GET request at some fixed time interval, and process results. Thats not what I want. I want the other way around: e.g. server to send data to my app, when something happens on the server side. That way I do not need to make constant requests from client side. I don't need the data to visually be displayed, just processed.
Can this be implemented in OSX with Swift?
You have two ways to achieve this:
Websocket:
Websocket is a full-duplex communication channel over a TCP-Connection. It's established via HTTP.
Long Polling:
Same as you said before but without responding directly. Your client makes a HTTP request and set a very long timeout timer. The server responds after something is happening. (More)
I would recommend you Websocket since it was built exactly for this use case. But if you have to implement it quickly you should probably go with long polling for now, since the barrier to implement it is much lower and switch to Websocket later.
The XMPP spec states that the client should broadcast presence upon connecting to an XMPP server. Strophe has two methods to "connect" to an XMPP server: connect and attach. Connect does a full authorization and attach is for reconnecting to a pre-existing connection. When using attach, should the client broadcast presence to the server?
In my testing, it appears that if I do not broadcast presence on attach, the client does not receive messages (presence, message, or otherwise) from other users, and if the client attempts to send any stanzas, he is immediately disconnected by the server. It's as if the server has no idea the user is connected without the presence broadcast.
This seems as if I answered my own question, however, I'm wondering if there is perhaps a bug in the server or if I'm doing something wrong or is this expected behavior?
There is a bug somewhere - attaching is literally attaching - you are continuing the original session. The server doesn't even know it happened!
Something to watch out for - if you have the old code still open, and you have multiple things using the same session, you could easily end up with something like you describe.
If you're still stuck, it might be useful to see some code, or at least a log of the attached session (e.g. the disconnection from the server - what error does it give, etc.?).
I'm supposed to implement a web application where the user log's in and by that registers for some sort of events (in this case, alarms). When an alarm happens, the server needs to push the alarm to all of the clients.
At the moment I'm using
GWT on the Client side
Jetty on the Server side
Is implementing the server push by using Jetty Continuations a good idea? My requirements are:
the number of clients will be quite small (<20) but could increase in the future
alarms must not get lost (i.e. if the client will be down, it must not miss any alarms)
if a client goes down, other clients need to be informed about it (or at least the admin should receive some sort of notification, e.g. by Mail).
The main reason for using Comet (e.g. Jetty Continuations) is, that it allows to reduce the polling frequency. In other words: You can achieve the same thing without Comet, by using frequent polling from the client side. Which alternative to choose depends on the characteristics of your application - depending on that, each alternative can be more or less efficent than the other!
In your case, since you need notifications when a client goes down, it makes sense to use frequent polling. Comet (long polling) is not suited very well for this task: Because of its priciple, it can take a long time until a client sends a new request. And receiving a new request is the only way a server can know that a client is still alive (remember, that a web server - no matter if Comet or not - can never send a request to the client).
Your requirement states that alarms must not get lost, implies a more complicated solution than long polling or frequent polling.
Your client should send an acknowledgement message to the server, because your user could close the application just after the alarm message arrived, he/she can loss that alarm.
Also, your user should click an alarm message to acknowledge the server . You can put a time limit to acknowledge , if the client does not send an ack message , then you can assume that alarm has been lost..
Long polling with acknowledgment algortihm would be my choices to solve your problem..
This is specifically about GWT's RequestBuilder, but should apply to general XHR as well. My company is having me build a near realtime chat application over HTTP. Yes, I do realize there are better ways to do chat aplications, but this is what they want. Eventually we want it working on the iPad/iPhone as well so flash is out, which rules out websockets and comet as well, I think?
Anyway, I'm running into issues were I've set GWT's RequestBuilder timeout to 10 seconds and we get very random and sporadic timeouts. We've got error handling and emailing on the server side and never get any errors, which suggests the underlying XHR request that RequestBuilder is built on, never gets to the server and times out after 10 seconds.
We're using these request to poll the server for new messages rather often and also for sending new messages to the server and also polling (less frequently) for other parts of application. What I'm afraid of is that we're running into the browsers limit on concurrent connections to the same domain (2 for IE by default?).
Now my question is - If I construct a RequestBuilder and call it's send() method and the browser blocks it from sending until one of the 2 connections per domain is free, does the timeout still start while the request is being blocked or will it not start until the browser actually releases the underlying XHR?
I hope that's clear, if not please let me know and I'll try to explain more.
On the GWT Incubator doc page is an article explaining server push.
With said technique you only hold one connection open all the time.
Browsers allowed only 2 connections per hostname; that has now changed. 'Modern' browsers allow upto 6 simultaneous connections - it varies between browsers. See http://www.browserscope.org/ - network tab.
As regards the timer, it starts before GWT invokes xhr.send(), so your suspicion is right. See Request.java and RequestBuilder.java if you want to trace it out.
Seems like half the time, you answer your own question as soon as you post it.
Via: http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/http/client/package-summary.html
Pending Request Limit
- Modern web browsers are limited to having only two HTTP requests outstanding at any one time. If your server experiences an error that prevents it from sending a response, it can tie up your outstanding requests. If you are concerned about this, you can always set timeouts for the request via RequestBuilder.setTimeoutMillis(int).