Is there a way to notify the server when a device connects and disconnects from the GCM platform?
Connection can be implemented easily enough at the application level since I would be able to send a message to my server via CCS. Detecting when the device is offline does not appear to be so simple.
I was hoping that there was a control message I could tap into to detect this?
thenIn these types of scenarios's, the pinging methodology is the best. For example if your client suddenly looses all his batterypower and the phone suddenly dies. The client will therefore not be able to send a request to your server that he is no longer online. Simultaneously, on the server-side, he is still flagged as "online".
The pinging mechanism reduces this problem by proposing a solution such that "If a ping is not received in a timely manner then flag the user as offline".
The Openfire plugin at the server side is one of the best one available till now that does this job for you. You can give it a shot.
Hope that Helps!!
There is the roster flag which indicates this:
connectionConfiguration.setRosterLoadedAtLogin(true);
Related
I have an Android application that has a chat client as one of its features. The chat client uses XMPP based on the Smack library for Android and running Openfire as XMPP server in the background. The connection is established using BOSH The whole XMPP connection handling is implemented as a service to run and listen in the background for incoming messages even if not activity of the app is in the foreground. So far, everything works perfectly fine.
The only problem seems to be the sleep mode. In the emulator (when set to "Stay Awake") or with the phone in use, the XMPP connections is holding and the app can send and receive messages. However, once the phone goes into sleep mode, the XMPP connection breaks down -- I can see it in the Admin Console of the Openfire server that the user is offline. Intuitively, I want to receive messages all the time like, e.g., WhatsApp.
Of course, I've searched online including Stackoverflow, but I couldn't get a definitive answer. Often the use case seems to be that a task has to be performed periodically, say, once every hour. But this doesn't seem to fir in case of a chat client. Since I assume this is a common use case -- after all, there a so many chat apps or apps with chat features out there -- these are my question:
How to I have to change / extend the app that I can receive chat message while the phone is sleeping?
I've stumbled upon WakeLock. Is this the way to go or are these not suitable for my use case?
Since Lollipop, there's also the JobScheduler API which itself uses WakeLock. Any better?
How does, for example, WhatsApp handles this case?
On a side note: I have problems with the sleep mode using the emulator for debugging. When I switch off "Stay Awake" in the emulator, the screen goes black after 1+ min and the XMPP connection breaks. But I somehow have no idea how to wake up / switch the emulator back on once it went black. Android Studio actually tells me at some point that the device or something is gone, and I have to restart the emulator again.
The exact way to resolve this issue is by using push notification.
It is the natural behavior of XMPP connection to get disconnected after the specified idle interval i.e when the device goes to sleep.
Coming to the case of WhatsApp, it also uses the same XMPP and maintains a server which acts as a wrapper class on the messages exchanged. This server checks the message status whether it is delivered or not. If not delivered, it sends a push notification, now at the device end in the push service when a message is received, it checks if the connection is active and is authenticated or not.
If not authenticated, it re-establishes the connection. In this way, the most chat apps manage this timeout exception.
Hope this helps :)
You don't need push notifications, you don't need WakeLocks. Instead simply
Whitelist your app from doze mode
Use a sticky (START_STICKY) background service
Use Smack's ServerPingWithAlarmManager
Act on CONNECTIVY_CHANGED intents send by Android, and use XMPPTCPConnection's instantShutdown() in that case.
I want to monitor firebase client connections from my java server.
I have found a lot of examples on how to use onDisconnect from the client side (iOS), and it works great.
But is it possible to monitor client connections from a java server using the java server sdk? I simply want my server to know about user disconnects, but without the client having to 'tell' the firebase database that it has connected/disconnected.
The reason for this is mostly security, and a wish to trust the client as little as possible to do important tasks. Ideally most of my data should be 'read only' from the client, except for some 'write only' request queues consumed by the java server.
From the firebase java server documentation: https://firebase.google.com/docs/reference/serverreference/com/google/firebase/database/OnDisconnect
The OnDisconnect class is used to manage operations that will be run
on the server when this client disconnects. It can be used to add or
remove data based on a client's connection status. It is very useful
in applications looking for 'presence' functionality.
It seems like what I want to do is possible and supported, but I'm having a hard time figuring out how to make my server monitor 100-1000 connections realtime.
Lets say I'm monitoring a database reference that I know clients are monitoring. In that case none of the options to 'remove on disconnect' or to 'set on disconnect' are useful.
Thanks a lot for reading this, I'm REALLY loving firebase right now, just a few more issues to figure out :-) Also sorry for my english, I'm not a native speaker.
I've been through different questions about this topic, however, none of them have cleared my doubts on the best approach notifying the client side of a server-client IM app.
The Problem:
The whole problem is how to notify the client application of updates. I've alread seen the following approaches:
Clients keeps checking for updates: From time to time, client app performs a check in the server to see if there are updates for that specific user;
Problem: it is not performatic at all. Suppose you have one million users and each one of them checks for new updates every second. Serve would have to deal with one million requests per second. Wont work.
Client app opens a socket: The client app opens a socket and sends its address to the server. Server, by its turn, persists this information and connects to the socket whenever it needs to notify the client of some update.
Problem: Often the client will be connected to a NAT, so, the IP it has access to is in a non-visible range. In order to send messages to this client, a port forwarding in the NAT would have to be configured, which can't be done.
Despite of the technology, I think this approach will always be used, however, I have no idea how the problem described above can be solved.
Google Cloud Message (GCM): use the GCM service to notify the client of any update. Problem: It does't seems right to use a third server to handle the IM and it raises concerns about the scalability of the system. When the number of messages and users increases exponentially, it seems that the service will go down. Despite that, it seems that passing the information for two servers before delivering to the targets just adds bottlenecks in the process.
A combination of 2 and 3: uses GCM to reach the client when the last persist addres is no longer available.
Problem: same as described in 2
XMPP: I've seen many answers indicating the use of XMPP for IM applications, however, XMPP is a protocol - as per what I've foun in the web. I don't see how it can solve the problem described in 2 for instance.
Given the options above, can someone indicate me what line should I try to go for? Which one of these approaches has the best chances of success?
Thank y'all in advanced.
Use Google Cloud Messaging. Opposing to what you stated this service is built to scale to billions of users it will generally not introduce performance bottlenecks.
What you basically want to do is to use the messaging service to wake up devices. If you insist you can then still use your client server approach and thus your own protocol to have the client lookup new messages from the backend.
when building a server, one sometimes performs asynchronous tasks from client to server (which responds to client in asynchronous time),
or the server needs to send the client a message
now if the client is listening at all times (meaning polling) it takes a lot of resources which is problematic
here is where I assume the operating system steps in and assumes the role of polling for the appropriate port, and letting the application know using the appropriate event (the application subscribes using the OS API)
am I right in my assumptions?
how do I subscribe to a port using the OS's API? (lets say android for the sake of argument)
how is a message from server to client work exactly?
and how does the server know the client's IP at all times?
I have seen many questions in the subject, but wasn't able to figure out the big picture
Edit:
I am using GCM in android, but have seen other apps that does not use it and still manage to do it right, also it's a more general question as to what is the right approach in java VS. any operating system it uses (ubnutu, windows, android, etc.)
Totally right - polling is typically a waste of resources. Until recently, many apps would either keep a socket open and poll every few minutes to keep it alive, or make periodic HTTP calls to a server.
Nowadays, Google Cloud Messaging is used by most apps to push data instead of constantly polling. As you correctly guessed, this is implemented by maintaining a persistent connection with Google's servers. The advantage of this is that it's very efficient for battery life, and that all apps can use this one resource to send push notifications, instead of each app having to poll a different server or create its own persistent connection.
The idea is that you send requests to GCM from your server (this can be in response to user activity, etc), which sends it to all of the client's devices. You can either send a message with a small payload (up to 4kb) or a "send-to-sync" message, which tells an app to contact the server (e.g. to sync new data from the server after user changes).
here is where I assume the operating system steps in and assumes the role of polling for the appropriate port, and letting the application know using the appropriate event (the application subscribes using the OS API)
GCM pushes messages to clients, so there isn't active waiting like you'd see in a simple polling system.
how is a message from server to client work exactly? and how does the server know the client's IP at all times?
There's no need for servers to know the client IP, as any online android device will typically maintain a connection with GCM. Targeting specific users is done via User Notifications.
(Oh, and I realize that your question is more general than just Android, which I have more experience in, but iOS has a similar system in place. Some developers I've met like to use Parse for managing push notifications).
I'm programming an Android multi-player game, which basically consist of a server where the clients connect and exchange messages. When the player connects to a server, a player list is return to him/her. A player can then select a user to challenge - of course he must select a player from the player list, which only contains connected users.
When a player1 challenges player2, a message needs to be transmitted from player1 to the server, which in turn must send a message to the player2, notifying him about the challenge. The player2 can then accept/decline the challenge.
I can use the following techniques to make this happen:
Use custom server/client with Java socket programming. The server basically accepts a connection from the client, spawning a new thread for each connected client. The problem with this are:
There needs to be a persistent connection open from client to server wasting battery life of the android phone. This is not really big limitation since the battery isn't consumed that much.
When I'll want to develop another game I'll have to rewrite the client/server code from the scratch - also choosing another port to listen for incoming connections - the whole concept gets rather difficult to maintain.
I'm also worried if this is the way to do it. Spawning another thread for each clients sound quite a lot if thousands clients are connecting at the same time. But I'm guessing the PC games do it like this. Not sure about android.
Use Java REST jersey to build the client-server on top of HTTP. This would be a perfect solution if the server could easily send notifications to clients. There are actually multiple design decisions here:
the client pulls the server for any new data/notifications every few seconds - this is really bad, since we're stuck with non responsiveness, delay, etc.
the client can send a waiting request to server, so the client receives the response only after some data becomes available. This is better, but can still produce a delay when two notifications one after another need to be sent to the user. The first notification is sent instantly, since the client already has a connection open, waiting for data to receive. But we would have to wait for the client to initiate another long http request to receive the second notification. The problem gets bigger as there are multiple notifications that need to be send in a row to a specific client.
the client can initiate a http streaming, where the communication is left open when the request is handled, so the server can also send multiple messages to client whenever it wishes. The problem here is that I don't know how well this works on Android. I've looked at several implementations:
Java jersey + atmosphere: didn't succeed in actually making it work. This seems the most promising, but I don't want to spend too much time on it, since I'm not even sure if it does what I want.
Deacon: seems pretty neat, but after seen the video tutorial on their official web page, I'm not sure that it can do what I need. When a player1 challenges player2, can it send a notification to player2 letting it know about the match request?
I would be glad to know how other multi-player games handle the network communications, if the two players are playing the game over the network.
I'm also open to a totally new suggestion how to achieve what I want. I can pretty much code anything, so don't hesitate to let me know of some more difficult way to achieve the network communication.
Let me also mention that I'll be glad to implement a totally specific method to work in my case, so it can be anything that will do the job done, but I'm also looking at more general way for communication between clients and server. So that I can program an interface/whatever and reuse the code in other android games, android applications.
I hope I presented the problem allright and that I'll receive some valuable answers.
Thank you
You should take a look at XMPP. It's a protocol (originally created for chat programs) that allows sending of xml data between users.
It has a separated client-server relationship, so that you can focus on developing a client application fit for phones, and a different server depending on your needs.
There are loads of information available on the protocol (I should know, I wrote a thesis about using the protocol in game applications), but you can start by looking it up on wikipedia to see if it is what you want.
aSmack is a library for creating android xmpp-clients. It takes some tweaking to set it up and get everything to work, but once you do, it's neat.
EDIT: relating to the answer suggesting using the C2DM:
from the c2dm docs "Sending large numbers of C2DM messages":
Are you sending C2DM messages too frequently? If you need to communicate with your application frequently over a short period of
time, C2DM is probably not the best solution. Instead, consider
implemeting XMPP or your own protocol to exchange messages, and use
C2DM only to send the initial notification.
It sounds like Android Cloud-to-Device-Messaging might be what you need
Push notifications without the app having to keep a connection open
I would vote in favor of some message passing technique - like activeMQ, rabbitMQ, zeroMQ eor something like it. On the server side you may stick with java , or javascript ( like
node.js ) - such solution would provide most performance and minimal latencies.
If latency is not that critical, you may as well use REST calls with JSON