Re: WO server to connect to Apple's Push Notification Service for iOS
Re: WO server to connect to Apple's Push Notification Service for iOS
- Subject: Re: WO server to connect to Apple's Push Notification Service for iOS
- From: Andrew Kinnie <email@hidden>
- Date: Tue, 15 Feb 2011 17:04:19 -0500
Thanks. This should help, once we start actually developing it (i.e. have more complete requirements). Evidently, we need to also support Android, so we need to research that as well.
Andrew
On Feb 15, 2011, at 4:24 PM, Mertz Stéphan wrote:
> Hi,
>
> Here is the code I used some time ago:
>
> import java.io.ByteArrayOutputStream;
> import java.io.DataOutputStream;
> import java.io.File;
> import java.io.FileInputStream;
> import java.io.IOException;
> import java.io.OutputStream;
> import java.net.UnknownHostException;
> import java.security.KeyStore;
> import java.util.Enumeration;
>
> import javax.net.ssl.KeyManagerFactory;
> import javax.net.ssl.SSLContext;
> import javax.net.ssl.SSLSocket;
> import javax.net.ssl.SSLSocketFactory;
>
> import com.webobjects.foundation.NSData;
> import com.webobjects.foundation.NSDictionary;
>
> public class IPhonePushNotification {
> private static String staticHost = /* Apple gateway push server name */;
> private static int staticPort = /* Apple gateway push server port */;
> private static String passPhrase = * your passPhrase */;
> private static String certificateAndKey = "/Certificats/iPhoneAPS.p12";
> private static SSLSocketFactory factory = null;
> private static IPhonePushNotification iPhonePushNotification;
>
> public IPhonePushNotification () {
> try {
> if (new File(certificateAndKey).exists() && staticHost != null && staticPort != 0 && passPhrase != null) {
> try {
> SSLContext ctx;
> KeyManagerFactory kmf;
> KeyStore ks;
>
> ctx = SSLContext.getInstance("TLS");
> kmf = KeyManagerFactory.getInstance("SunX509");
> ks = KeyStore.getInstance("PKCS12");
>
> ks.load(new FileInputStream(certificateAndKey), passPhrase.toCharArray());
>
> kmf.init(ks, passPhrase.toCharArray());
> ctx.init(kmf.getKeyManagers(), null, null);
>
> factory = ctx.getSocketFactory();
> } catch (Exception e) {
> e.printStackTrace();
> throw new IOException(e.getMessage());
> }
> }
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
>
> public static IPhonePushNotification iPhonePushNotification() {
> if (iPhonePushNotification == null) {
> iPhonePushNotification = new IPhonePushNotification();
> }
>
> return iPhonePushNotification;
> }
>
> private static String getJSONMessage(String msg, NSDictionary infos) {
> StringBuffer jsonMessage = new StringBuffer("{\"aps\":{\"alert\":\"" + msg + "\",\"badge\":0,\"sound\":\"default\"}");
>
> if (infos != null && infos.count() != 0) {
> Enumeration l_enum = infos.keyEnumerator();
> while (l_enum.hasMoreElements()) {
> String l_key = (String) l_enum.nextElement();
> String l_value = (String) infos.objectForKey(l_key);
>
> jsonMessage.append(",\"" + l_key + "\":\"" + l_value + "\"");
> }
> }
>
> jsonMessage.append("}");
>
> return jsonMessage.toString();
> }
>
> public synchronized void sendMessage(String msg, NSDictionary infos, NSData deviceToken) {
> if (factory != null) {
> SSLSocket socket;
>
> try {
> socket = (SSLSocket) factory.createSocket(staticHost, staticPort);
> socket.startHandshake();
> sendMessage(socket, getJSONMessage(msg, infos), deviceToken);
> } catch (UnknownHostException e) {
> e.printStackTrace();
> } catch (IOException e) {
> e.printStackTrace();
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
> }
>
> private synchronized static void sendMessage(SSLSocket sock, String msg, NSData deviceToken) throws Exception{
> OutputStream sos = sock.getOutputStream();
> ByteArrayOutputStream bos = new ByteArrayOutputStream();
> DataOutputStream dos = new DataOutputStream(bos);
> dos.writeByte(0); // 1 byte command
>
> byte[] binaryDeviceID = deviceToken.bytes();
>
> byte [] token = binaryDeviceID;
> dos.writeShort(token.length); // 2 byte token length
> dos.write(token); // token
> byte [] payload = msg.getBytes("UTF-8");
> dos.writeShort(payload.length); // 2 byte msg length
> dos.write(payload); // payload
>
> byte [] output = bos.toByteArray();
>
> sos.write(output);
> sock.close();
> }
> }
>
>
> Example of use with WO:
> while (l_usersEnum.hasMoreElements()) {
> EOUser l_user = (EOUser) l_usersEnum.nextElement();
>
> if (l_user.parameterValueForKey("deviceToken") != null) {
> if (l_passageCreation && Utils.booleanValueOf(l_user.parameterValueForKey("pushPassageCreation"))) {
> final NSDictionary infos = new NSDictionary(
> new Object[] { l_pssg.valueForKey("pssgID"), l_user.parameterValueForKey("pushServer") },
> new Object[] { "pssgID", "server_name" });
> final String msg = localizer().localizedStringForKeyWithDefault("A record was created");
> final NSData deviceToken = (NSData) l_user.parameterValueForKey("deviceToken");
>
> new Thread(new Runnable() {
> public void run() {
> IPhonePushNotification.iPhonePushNotification().sendMessage(msg, infos, deviceToken);
> }
> }).start();
> } else if (l_passageCreation == false
> && Utils.booleanValueOf(l_user.parameterValueForKey("pushPassageUpdate"))
> && l_pssg.userMedecinDuDossier() == l_user) {
> final NSDictionary infos = new NSDictionary(
> new Object[] { l_pssg.valueForKey("pssgID"), l_user.parameterValueForKey("pushServer") },
> new Object[] { "pssgID", "server_name" });
> final String msg = localizer().localizedStringForKeyWithDefault("A record was modified");
> final NSData deviceToken = (NSData) l_user.parameterValueForKey("deviceToken");
>
> new Thread(new Runnable() {
> public void run() {
> IPhonePushNotification.iPhonePushNotification().sendMessage(msg, infos, deviceToken);
> }
> }).start();
> }
> }
> }
>
>
> Le 15 févr. 2011 à 20:43, Andrew Kinnie a écrit :
>
>> Greetings all,
>>
>> As I am now an iOS developer (as well as a part time WO developer), and my new employer has decided to build a server to handle the iOS push notifications, I thought perhaps building such a thing based on WebObjects might be worth considering.
>>
>> Has anyone used WebObjects to create a server to handle the APNs calls? (i.e. - I think - communications from the device with the token to the server, then handle the pushes to the Apple server with the data and relevant devices) It seems comparatively simple, but I thought I'd ask. There was a short thread (4 messages) a little over a year ago about this, referencing http://code.google.com/p/javapns/ and suggesting a component using it be included in Wonder, but I have not seen anything else.
>>
>> Any thought? Suggestions? etc?
>>
>> Thanks in advance
>>
>> Andrew
>>
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden