I'm writing an app that use xmpp to exchange messagge between users. If I have two devices logged with the same account,any xmpp message is received only by one device, maybe the one with the fast connection? Anyway how I can do to ensure that any message will be send to any device connected with the receiver account? I'm using ejabberd server and XMPPFramework for ios.
You can login simultaneously in two different devices provided you are using different resource names when logging in. You can check sessions and resources the user has used to sign in on the server
Related
I am developing a chat app using ejabberd server for both IOS and Android. I also wrote a module for ejabberd to get the offline messages sent to my own server api .
my own server api will send notifications to the IOS/Android platforms using FCM.
On the client side , if the application is in the foreground or the background , it will stay connected to ejabberd and if the client receives the message then ejabberd will send the message delivery status.
I am facing an issue while the app is terminated ( service is not running ) which means it is not connected to ejabberd (offline) . if i send a message to this app while it is not terminated , it will receive a notification but the message still undelivered . how can mark the messages as delivered when receiving the notification while the app is terminated.
to explain it more , the same functionality is working fine with whatsapp :
device A has whatsapp installed and whatsapp was turned off (terminated)
Device B has whatsapp running
Device B sends a message to device A
Device A receives a whatsapp notification
Without doing anything on Device A , the message status on Device B is marked as delivered .
How can I implement this scenario with ejabberd ?
In case someone went into this issue , here is the solution that I implemented with help of #Mickaël Rémond from his answer.
I configured ejabberd to send the offline messages to an http service ( your own server) please refer to this link for further on how to do it
your server should catch the above call and generate a notification message (FCM ) in my case and send it to recipient device
recipient device will catch the notification which includes the message
recipient device will call http service (your own server backend)that responsible for sending the deliver ack to the original sender . you need to pass from, to , stanzaId , vhost with this call
backend server will use ejabberd-api (set of exposed apis to manage ejabberd through rest apis calls) to send delivery message using this api
please note the following notes also :
sending the delivery message from your own server to ejabberd will not delete them from ejabberd database
if the user re-connected to the ejabberd server then the recipient will receive the message again from ejabberd .
It is probably too complex for a simple Stack Overflow question, as you need to integrate several moving part on client and server:
You need to execute code in background when receiving push notifications on iOS (you need that property set on your app in your app provisioning profile and have code to handle that). The client will initiate an HTTPS query to let the server know that the message was delivered.
You need to have an endpoint that will get the delivered HTTPS calls and generate either a message ack or a chat marker on behalf of the user and route it in ejabberd.
In real world, this is not enough if you want to take into account the fact that you can only have 1 push in the queue on APNS. If you have several messages sent while the device is not on the network, you will need to have the device check all received messages while offline on the server, otherwise you will lose messaging.
You need to rely on XMPP Message Archive Management (MAM) to handle that history.
As you see, this is not a simple few tens of line of codes but need real design and involved work.
Is it possible to configure Firebase app server to receive notification when there are messages exchanged between two other devices over Firebase Cloud Messaging?
So for instance I want to save these messages via my app server to the database. Currently I do it with additional REST request when I receive message on target phone.
However I want to avoid two jobs on target devices(listening/receiving the message and sending a request to save it) I'm thinking there must be an option where User sends a message from their phone and it not only arrives at target device but also notifies server?
There is no way to register your own observer that hooks in to Firebase Cloud Messaging's message sending mechanism.
There is also no capability to send messages directly from one device to another. There is always a piece of code that you deploy to a trusted environment (e.g. an app server of Cloud Functions) involved in sending so-called downstream messages to devices.
Two approaches that may accomplish the same need are:
Implement an XMPP server that sits between the devices sending messages and the FCM server that delivers messages to devices
Implement an intermediate service where the devices send the message, which then in turn calls FCM. This is a more generic approach of the previous one and is described in this blog post and in this use-case in the Cloud Functions for Firebase documentation.
I'm kind of starting programmer and on Objective-C. So I want to make an app for iOS that receives messages from a server. These messages are inputed manually, and send to all iOS connected to the server. People connected will receive a Push Notification, if they aren't connected to internet they will receive when they do and run the app.
So my question is: do I need to use a server to do this (sending messages for multiple iPhones)? In case of yes, with is the best server? TCP/socket?
If your only purpose behind using is to send push notifictaion message, then you dont need to spend on that. There are some service providers available which allow you to send notification from there website. for ex: you can use urbanairship. You need to register device token from your Xcode project using their SDK, and then you can send notification from their website.
Thanks!
XMPP allows users to connect to the server from multiple clients simultaneously, using the same account. I built an application that does this but if the desktop client is enabled, I do not want the users to be able to connect using a mobile client. This is for a game and being connected to both causes problems.
So what I'm wondering is:
Is it possible to detect if there are other clients connected using the same account. If I can check for other clients, I can auto logout the user.
#Flow was on the right track. If all of your client instances use the same resource, in most servers, the later-connecting client will replace the older session. The older session will get a conflict stream error, and be disconnected. You MUST be careful not to auto-reconnect with the older client, or you will have written the "dueling resources" bug.
If you had control over your server, you have a chance at configuring it to allow a maximum of one resource for a given user, in which case the newer connection will fail with a conflict error, but you'll have worse user interface problems if you head down that path; there will be no way to get the second client logged in, even if you wanted to.
Finally, all resources for a given user are subscribed to that user's presence. As long as your client sends presence in:
<presence/>
you will receive presence from each of your other devices:
<presence to='user#example.com/resource1' from='user#example.com/resource2'/>
<presence to='user#example.com/resource1' from='user#example.com/resource3'/>
<presence to='user#example.com/resource1' from='user#example.com/resource4'/>
You could use this to decide which client is current, perhaps by adding an extension to the presence like XEP-0115.
Give the desktop and mobile client a fixed but different resource string. If the mobile client logs in, it can detect the presence of the desktop client by looking up the presence/availability of the resource of the desktop client and vice versa.
Then you only need to implement an custom XMPP ad-hoc command (XEP-0050) that tells the conflicting resource to log out.
It would be the servers responsibility: to reject a login from a client that is not accepted. I don't know if servers are able to blacklist xmpp clients but, in case you use openfire, you should be able to write an extension.
I have created an XMPP chat application for Android and iPhone. While testing the app in jwchat.org, users who are created from iPhone devices are shown as 'stalker', and Android usernames are shown as online / offline. What does 'stalker' mean? Because of this, messages are sent and received from Android to iPhone, but iPhone devices' messages are not recieved by Android devices. Can anyone please help me?
"Stalker" is an unfortunate term that is embedded in the user interface of your client, not a standard part of the protocol. It likely refers to people who are in your roster as type="from", which indicates that they are subscribed to your presence but you are not subscribed to their presence. If you want to change this state, send them:
<presence type='subscribe' to='stalker#example.com'/>
Once they accept with:
<presence type='subscribed' to='you#example.com'/>
You should have each other in the type="both" state on one anothers' rosters.
It sounds like a presence problem on the iPhone app -- that it is successfully logging in/authenticating to the xmpp server, but then failing to send an xmpp presence stanza.
Do you have any traces of the xmpp communication?