I've been looking for an answer everywhere to no avail. I've developed an app for a client. This client works with money online so he has great security on his servers and the normal security policies, one of these policies is restricting external connections from domains, so the only way to register connections is by specific IP addresses. My problem is that the framework responsible of sending push notifications waits for an answer from the server to know if the push notification was delivered to a user, if the server response timeouts or the response says the notification was undelivered, the framework tries to send that notification again. This process is tried three times and after the third the framework doesn't even check for delivery status anymore and keeps working on the rest of notifications. The problem is that apple responses come from different IPs and if the IP responding is not one of the IPs registered on the client's security policy, the final user will receive three push notifications instead of just one.
I`ve been trying to get the IPs by trial and error but it is frustrating and I've got more than 30 different IPs so far. Is there any documentation of the IPs Apple uses to respond to push notifications? Has anyone got a list of IPs by any other means?
Sorry for the long post.
According to this technical note from Apple:
The IP address range for the push service is subject to change; the expectation is that providers will connect by hostname rather than IP address. The push service uses a load balancing scheme that yields a different IP address for the same hostname. However, the entire 17.0.0.0/8 address block is assigned to Apple, so you can specify that range in your firewall rules.
Related
I am working on an application which GET and POST information to a server. I am doing so using AFNetworking framework. My aim is to push a notification to a client whenever someone posts new info to the server. Eg: a new grade is published, the student who's grade was published must receive a notification on his iDevice.
Although I am not familiar with how Apple Push Notification works, from what I read I concluded that I need to add server side code in order to trigger a notification.
Note that I don't have access to the server. Service is provided by Fedena.
Any suggestions or hints from where to start?
APNS needs a server in order to work. The usual flow goes like this:
The iOS Application asks user to enable push notifications
Upon access granted, a device token is generated and then must be sent to the server.
Your server must be setup with the proper APNS certificates generated from the Apple Developer site
Then in your server's, when a new post is created, you need to add some logic where you load all the APNS token you've received already and then send the notification to the devices.
This is a very simple flow description but I guess you understood that you need to have access to the server to be able to do what you are trying to achieve.
Some third parties exists to handle push notifications (like Urban Airship), but those push notifications are usually pushed manually from a person, and not triggered from a server event
I recommend that you can use secondary server of your own as intermediate and use it as infrastructure back bone.You can use SignalR library. Use secondary server as to create connection between two devises. One client will push events and another client will listen to events.
Here is the link to the signalR library code written in IOS.
I am currently using these library. What you can do is start hub and connection using these library.
This library allows invoking method on server. Something like this.
[_hub invoke:#"MehtodName" withArgs:params];
What i would do is to create event registry on server. So one client can listen to event on server and other can push events or vice versa.
So your student device can invoke method "subscribe to events" and server will add it into the registry list. You can create secondary service "Publish Events". Grade publisher can publish via calling this method. Here publish events will look up registry and find interested clients and call desired method on client.
Read more about signalr through this site.
Benefit of using Signalr Over APNS.
Cost Effective. As this will save you money which you might have to pay to Apple for pushing notification.
Can Easily make it cross plateform in future. Just have to impletement similar library in Android/Windows.
Quicker as the data does not travel to apple server from your server.
Worst case you can fallback to apns any day, just put push notification code in any of your secondary server methods.
I have done battery and performance testing as well and works perfectly fine.
If you wanna know, here how it handles connection which is very reliable.
SRAutoTransport chooses the best supported transport for both client
and server. This achieved by falling back to less performant
transports. The default transport fallback is:
SRWebSocketTransport
SRServerSentEventsTransport
SRLongPollingTransport
Let me know if you have anyother question. i am currently doing similar work, might be able to help you with your issue.
We are working with IBM MobileFirst Platform 7.0 and are trying to send push notifications through the Apple APNS server. We are not using a SOCKS proxy.
As far as we know, we have opened the relevant ports through an F5 load balancer from the MFP server(s) to the internet:
gateway.sandbox.push.apple.com:2195
feedback.sandbox.push.apple.com:2196
gateway.push.apple.com:2195
feedback.push.apple.com:2196
However, we are still seeing tracing errors when sending push notifications of this form:
[10/22/15 9:43:01:362 CEST] 00000153 ApnsConnectio I com.ibm.pushworks.server.notification.apns.ApnsConnectionImpl sendMessage Failed to send message Message(Id=7; Token=XXX; Payload={"aps":{"alert":{"body":"Test body","action-loc-key":null}},"payload":"{\"id\":\"XXX\",\"title\":\"Test body\",\"tag\":\"Push.ALL\"}"})... trying again after delay
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:208)
at java.net.SocketInputStream.read(SocketInputStream.java:134)
at com.ibm.jsse2.a.a(a.java:260)
at com.ibm.jsse2.a.a(a.java:204)
at com.ibm.jsse2.aq.a(aq.java:684)
at com.ibm.jsse2.aq.h(aq.java:790)
at com.ibm.jsse2.aq.a(aq.java:371)
at com.ibm.jsse2.h.write(h.java:20)
at java.io.OutputStream.write(OutputStream.java:87)
at com.ibm.pushworks.server.notification.apns.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:302)
at com.ibm.pushworks.server.notification.apns.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:292)
(I have redacted the token and the Id).
I would theorise that the network connectivity is not set up quite correctly, but it is possible to telnet to each of the above addresses on the above ports from the MFP server, so on a superficial level, connectivity seems to be working.
Is there a way we can verify more deeply whether we have sufficient network connectivity to those servers to send push notifications, ideally independently of MobileFirst? I understand a persistent connection is required ("...The provider connects with APNs through a persistent and secure channel..."), and perhaps this is where things are not set up correctly.
My answer would be a continuation of the answer to your other push-related question: Is 1-courier.push.apple.com needed for IBM MobileFirst APNS notifications? What is it for?
Did you try to also allow access for 1-courier.push.apple.com:5223 and observed if things do start working now? I think you should allow it.
If I want to make sure that a device receives a message, over the network, for an app used by sellers in a shop for example.
I heard push notifications are not 100% reliable, sometimes some of the notifications don't arrive, or not on time.
The app could be in a shop, where the staff communicate with one another, and there could be 10 devices connected. (ipad, iphones)
edit 1: I heard about sockets, is it the right direction to go?
EDIT 2:
I am not sure why a socket should be used, rather than a webserver for example, I found these 2 sentences (source raywenderlich) :
You can send connected clients data whenever you want, rather than requiring the clients to poll.
You can write socket servers without a dependency of a web server, and can write in the language of your choice : don't understand what the "dependency" is?
Does it also mean :
Sockets let 2 (or more) specific devices to connect one another in a private connection, compared to webservers where everybody could connect if there is no login/password?
EDIT 3 : Maybe a bluetooth solution with MultiPeerConnectivity would be better...
Sockets, and push notifications in general, are only as reliable as the network the user is connected to. If your looking to circumvent network reliability where a 100% success rate is guaranteed, in a Shop environment where users are in close proximity, you can look into GKSession as part of the GameKit.framework
Or you could look into Bonjour or client/service discovery protocols that makes the process of "knowing" peers in a network
I see you tagged Parse.com, again, the reliability of Push Notifications is highly dependent on the reachability, however, most issues that arise with Parse is dev-end related, not product related.
EDIT I forgot to mention MultiPeerConnectivity
If you use TCP sockets, you are guaranteed the message will be delivered, and very quickly too.
However, the application would have to be open (and most likely in the foreground) to receive the messages. You can always have the server wait till the client connects to send the message.
I would suggest using a combination of both TCP sockets and push notifications (for when the app is closed).
i went through this question
Lost messages over XMPP on device disconnected
but there is no answer.
When a connection is lost due to some network issue then the server is not able to recognize it and keeps on sending messages to disconnected receiver which are permanently lost.
I have a workaround in which i ping the client from server and when the client gets disconnected server is able to recognize it after 10 sec and save further messages in queue preventing them from being lost.
my question is can 100% fail save message delivery be achieved by using some other way i know psi and many other xmpp client are doing it.
on ios side i am using xmppframework
One way is to employ the Advanced Message Processing (AMP) on your server; another one is to employ the Message Delivery Receipts on your clients.
The former one requires an AMP-enabled server implementation and the initiating client has to be able to tell the server what kind of delivery status reports it wants (it wants an error to be returned if the delivery is not possible). Note that this is not bullet-proof anyway as there is a window between the moment the target client losts its connectivity with the server and the moment the TCP stack on the server's machine detects this and tells the server about it: during this window, everything sent to the client is considered by the server to be sent okay because there's no concept of message boundaries in the TCP layer and hence if the server process managed to stuff a message stanza's XML into the system buffers of its TCP connection, it considers that stanza to be sent—there's no way for it to know which bits of its stream did not get to the receiver once the TCP stack says the connection is lost.
The latter one is bullet-proof as the clients rely on explicit notifications about message reception. This does increase chattiness though. In return, no server support for this feature is required—it's implemented solely in the clients.
go with XEP-0198 and enjoy...
http://xmpp.org/extensions/xep-0198.html
For a XMPP client I'm working on, the following mechanism is used:
Add Reachability to the project, to detect quickly when the phone is having connectivity problems.
Use a modified version of XEP-0198, adding a confirmation sent by the server. So, the client sends a message, the server confirms with a receipt. Later on, the receiving user will also confirm with a receipt. For each message you send, you get two confirmations, one from the server, one from the client. This requires modifications on the server of course.
When the app is not connected to the XMPP server, messages are queued.
When the app is logged in again to the XMPP server, the app takes all messages which were not confirmed by the server and sends them again.
For this to work, you have to locally store the messages in the app with three possible states: "Not sent", "Confirmed by server", "Confirmed by user"
I have implemented the Reachability class successfully. However, in my app I'd like to notify the user when a connection to our server only can't be made (but the regular internet is working).
Reachability is reporting that the iPhone successfully can reach a hostname, when I thought it might return an error b/c I was not on an authenticated network:
The hostname I use is 'foreverfreebank.com'. Again, Reachability's hostname check reports success.
However,
--to access this site via the web, one needs to use https in the browser, i.e. 'https://foreverfreebank.com'
Does Reachability account for this case? Or does the protocol part ('https') not count for anything?
I am confused b/c if you type in in the Firefox browser 'http://foreverfreebank.com', (leaving out the 's'), you get an error. That is, http:// should NOT be reachable.
Similarly, I have another site that requires VPN access to get to the site: http://checksforever.com. When I try the hostname: 'checksforever.com', Reachability reports success even though I am not on VPN.
Is this expected behavior? Thanks
You need to check reachability on a specific port (443 in this case). This is something that is not supported by Reachability API. Refer to this question, or this.
Relevant part from documentation:
A remote host is considered reachable when a data packet, sent by an
application into the network stack, can leave the local device.
Reachability does not guarantee that the data packet will actually be
received by the host.
So, basically Reachability doesn't test if the remote host accepts incoming connections. For this purpose, I suspect you'll need to open an URL connection and wait for time out/other errors.