Hi I am developing android application in which I want show whether other person is online or not so that person can intiate the communication.I thought about few solution :
1) Implementing heartbeat mechanism, in which device will send ping request to server after fix interval of time.
2) Server will send push type ping to client and client will give response on that so that server will know that client is online.
First case causes battery and data issue, while second one causes delay in push which will affect the process.
Is there any better solution for this problem? Apart from these or improvise version of above one.
nilkash. Virtually any method for checking network connectivity will at the end result in sending periodical pings between device and the server. Even push type ping will actually do the same (but it saves battery because push notifications aggregate messages for all applications in-to a single connection to a google server). So the best solution is just a proper combination of optimizations and you have to choose them depending on your requests.
Server pushes are power efficient, mostly because they reuse the
same connection for all applications, but the delay can be huge,
something like 10 minutes.
You can subscribe to connectivity
events and send "online" message to server once you are online. (But
not once you are offline because you are... offline). This will give
you immediate online events.
Do not send pings from device when there is no connectivity. Your application should be absolutely idle so as not to use battery.
There is no easy way to find out
when client goes offline on server side. You have to trade
traffic/battery for time resolution. More often you send pings, the
better resolution is. But you can't change ping interval for pushes,
so if you need better resolution, then you need to use your own
connection. But you can send other useful data through that connection too.
If you keep a TCP connection, then your pings can be
very data efficient: TCP keep alive packets are just 60/54 bytes.
But then you have to keep open connections with all clients on the
server. This may be a problem if you have a lot of clients.
The best combination may be something like that: you always send online message from a client when it becomes online. You keep TCP connection while the application is in foreground. You use the same connection to transfer data to and from the application. When your application goes to background you fallback to power consuming push based pings and do them at 10 minutes basis.
Related
Our server is scaling out with 1-3 instances in some specific period of time everyday. We have Azure Redis Backplane for connection persistency of signalr. In addition to this, the server doesn't ARR Affinity enabled. By the way we are using ServerSentEvents for Androids and WebSocket for iOS.
The problem is our mobile users(moto couriers) are disconnecting or reconnecting to SignalR server frequently because of their provider when the mobile signal is low.
We have checked all the things over mobile side. We pretty sure that we have one and only one signalr connection at a time. In addition to this when they are connected, we are storing their connectionids on persistent storage (SQL Database).
While sending a message to users we choose the latest connection id stored on Database. This means that we only sent to client's only one connection id.
However we get some feedbacks about the messages we sent over server popping up twice on their phones (Most of the time messages are received twice in the rush hours where server has 2 or 3 instances).
We are not able to trace it down why it is received twice especially on rush hours.
The question is, is there any chance this is about ARR Affinity? Because Redis backplane uses subscribe and publish methodology and since couriers are disconnecting/reconnecting frequently they have a chance to connect different servers, thus, when server sends a message, 2 servers might try to send that message and it is popping up on their phone twice even though they have one connection.
Additional info;
SignalR DisconnectTimeOut = 60 seconds
SignalR KeepAlive = 20 seconds
This seems to be the reason, when new connection request is made, you might need to drop existing one from other server, using replication.
if replication interval is short enough, it will minimise number of duplicates, for the rest, you might need to solve it on client side by ignoring last notification if notification hash/id is already received.
I have an Android client working in tandem with ejabberd XMPP server.
Observations:
Scenario 1: When I swipe-right the app (kill the app), the user goes offline on the server immediately. Its status is changed to offline at that very instant.
Scenario 2: However, when I simply shut-down the Wi-fi connectivity (data) of my Android Jabber client, there is a noticeable lag of a few minutes for the user to be marked offline on the server.
I can’t figure out what is the fundamental difference in the two processes.
What could be done in Scenario 2 to make it go offline immediately?
Scenario 1: When I swipe-right the app (kill the app), the user goes offline on the server immediately. Its status is changed to offline at that very instant.
In above case your Android xmpp client is sending presence as unavailable before closing your Android application, maybe your Android XMPP client is maintaining a background service which in turn maintains a persist XMPP connection (TCP socket) to XMPP server, when you close your application onDestroy() method of service will be called and in that one can check if XMPP connection is still connected. If yes then send presence as unavailable which will safely make user as offline on server and then disconnect XMPP connection (socket).
Scenario 2: However, when I simply shut-down the Wi-fi connectivity (data) of my Android Jabber client, there is a noticeable lag of a few minutes for the user to be marked offline on the server.
As I mentioned earlier, Android devices can maintain a persist XMPP connection in a service, when you turn off wifi and your XMPP connection (TCP socke) to server is still connected, there is no safe removal of user from XMPP server [client can't send presence as unavailable] means connection is just-hang up and Android client/XMPP server doesn't have knowledge of it. In such case now server will figure out client is hangup by client ideal time period [i.e there is no communication on socket for a fixed interval], and make user as offline. This process is time consuming so that you are seeing lag of a few minutes.
What could be done in Scenario 2 to make it go offline immediately?
You can configure XMPP server and make client
As this problem can be handled from XMPP client and server, from client you can fixed interval time ping, if you keep ping duration small enough you can detect lost connection (like broken pipe on socket), same way on server side if you keep ping inter [remember this is server to client ping] small you can detect loss of connection.
As I can see you are using ejabberd as your XMPP server, details given on this link says,
How to detect a dead connection?
One way to detect a dead connection is to ping the client periodically
and to kill the connection if the client doesn't respond. This can be
done using mod_ping. However, these ping packets might wake up the
client's radio, so a short ping interval might drain mobile batteries.
Therefore, it's not generally recommended to use an interval of less
than a few minutes. Either way, there's always some time window where
messages can be lost.
I'm going to make an android app that needs to work like an instant messaging (Chat) application, but a little different. It needs to send and receive some short messages, and it's important that it delivers the messages from a web server to the android client quickly (that's a synchronizing app).
Also, the internet connection may be unstable (like GPRS). The server application uses .net 4.5 (may be a windows service or web service)
I've searched around but the answers were not clear for my questions. My questions are as follows:
Is it better to use an open socket or check the server every few seconds? (max allowed delay is 15-20 seconds)
How much network traffic does a socket use in a day, if it is open and no message passes?
How many sockets can be open at the same time?
It really depends on what you want to do, but here are some answers :
Reopening a TCP connection every few seconds probably won't hurt. Close+reopen is how most HTTP connections work.
An idle TCP socket doesn't send any traffic at all, unless you enable TCP keepalive, but even then it is still very light (and often adjustable).
Usually a lot, but is really depends on your software and hardware. A desktop computer may have 1000 open connections on normal load (but can certainly handle more). A big server may handle millions open connections.
Depending on what your 'synchronizing' thing is, you should consider synchronizing with GPS time. It is present on most mobile devices and have a precision around nanoseconds (= all devices will have the same GPS time, give or take some ns). But then the server may need GPS time too, depending on what you do.
Also depending on your application, you should consider using UDP sockets. The good points are that you only need one UDP server socket to handle ALL the UDP clients (you can't do lighter), and that it is more reliable time-wise (when there is a problem, TCP may re-transmit with high delay, while UDP is all or nothing, = you handle up-to-date re-transmit yourself). The downsides are that it is unreliable (messages can be dropped or corrupted, therefore you may want to add some safety), and that some ISP may restrict UDP more than TCP (test yourself to be sure, but usually there is no problems). Note that with UDP, you may need to 'keep alive' yourself, by sending a dummy message, but it is only needed if the 'connection' is idle for too long.
I'm trying to develop a turn base game over XMPP. ( The only solution I found for multiplatform game ). I can send messages without problems. If the other user isn't online, the server (OpenFire) save it for later deliver.
The problem cames when a device change the network ( change from 3g to WiFi, change 3g IP... ) or the device lost the network ( turn off 3g, wifi or lost connection ). The server thinks that the device is online and send the message but it ( obviusly ) never arrive, so packet is lost.
I know one solution. Implement ACK over my game protocol, but I don't like this idea to much. Do you have any other suggestion? I think this is a server problem. Do you know another server witch implements TCP or ACK?
Thank you!!
EDIT: I do that: Connect device to server. I turn down the 3G and WiFi connectivity to the device. Android and the server still thinking that the connection is alive.
http://issues.igniterealtime.org/browse/SMACK-331
PD: I ask to openfeint for they multiplayer api, but they didn't asnwer me...
Although BOSH will likely work in this case, another option is XEP-0198: Stream Management. This will allow you to have all of the performance of a fully-connected socket, along with quick reconnects, positive acking, and queuing while un-acked or disconnected in both directions.
Under some conditions TCP/IP is not reliable. This is why ACKs, message receipts, IQs or other extensions in XMPP can solve this problem.
I have done lots of mobile programming over the years, also often with Openfire. But I have not seen lost messages. So I assume that there is a problem in either the library you are using on Android, or the Openfire version you use.
Instead of using raw sockets you can also use BOSH:
http://xmpp.org/extensions/xep-0124.html
BOSH is based on WebRequests like Comet and works very well in environments where you switch or loose often the connection. It can keep the connection alive until your network is back and does not result in connection drops when one or more requests fail in a row.
I too came across this issue and been trying to figure out a proper way to get this resolved.
Problem for me is that I set the offline messages policy to "Always Store" and thus XEP-0184 doesn't really help out to determine if a message is not getting delivered to its receiver.
Providing this scenario:
- I have 2 users chatting, call them A and B
- A sends B a message while B's connection just got lost
- The message got dropped and A is not notified
- In this case A does not know that the message got dropped, it'll just assume that the message is delivered to the server, server will eventually deliver it to B
- B lose the message forever
So I temporarily put in a work around for this... i store all those messages that are not delivered (i.e. haven't receive the message delivery receipt) into a queue, then periodically (say, 6 minutes - it's the time when those dead connections got wiped) check every message of the queue to see if the intended recipient is "Online" AND the receipt's still not received... If it's the case, then I mark that message as "Failed delivery"
This is quite a terrible way to fix it (please advise if you have a better way of doing it). I think the best thing to do is to have the server to do this: if message failed to deliver and the offline message policy is "Always Store", then we store it to "ofoffline" for delayed delivery.
This is an old one, but I was solving such an issue recently. It helped me when I set the XMPP resource (the last part of full JID) to something reasonable, when building connection. Otherwise it will be random generated on each reconnect - and that changes the full JID.
As part of an Android app I'm developing there is a chat room feature. We have a server which can process the incoming messages and store the messages. Is it better to keep a socket connection open between the phone and the server so the server can send any new messages to the phone, or is it better for the phone to poll the server for new chat messages?
It is bad solution with poll for app that have randomly posting data. What I want to say is that polling data is useful when you have something that is happening discrete like every 5 minutes or something like that. this is not the case with chat, some user can post something ones in a hour , some can post 30 times in 2 minutes
so keep your sockets open
Polling lacks real-time connection and a persistant connection is battery draining. I think that what you are looking for is a combination of "push"-ing and persistant connection. You would wake your phone via push, and then establish a connection via sockets to handle chat.
I suggest reading this article.
I'm not sure if it mentions c2dm, the google push service.
I would keep the socket open if you are worried about instant messaging, it takes time to setup the socket connection especially if you are using the GSM connection. I have seen it take 10 secs or more to open up a socket on 3G, much less if on WiFi.