3
votes

Use case: Android devices cannot contact Ruby On Rails server directly (it is behind firewall) and I cannot have a Internet server to receive requests directly. I need to have internal Rails server to retrieve messages from Android devices and instead of a pooling strategy, I've seen that GCM + XMPP would fit perfectly.

But, I could not find any info on how to code such scenario in Ruby/Rails.

How can I not only send push-notifications from my Ruby On Rails server, but also receive Upstream Messages from GCM (Google Cloud Messaging) connecting my Ruby On Rails server to Google CCS Servers?

  • for the Upstream, messages are originated from Android device, that is not the scope of the question
  • I know that I must use XMPP for that.
  • I know there are ruby gems for sending push-notifications from rails servers to Android devices, but all of them are HTTP based (at least, all that I've seen) and cannot do what I need
  • I know that Rails server would keep a connection opened (XMPP) to Google's CCS Servers (GCM Cloud Connection Server) to receive Upstream messages
  • I am aware of XMPP4r gem but cannot find code examples enough to integrate it with Rails

Any help is appreciated.


Log (or what I have done so far...)

  • 17/12/15: Trying to use this post as a starting point. I have created a project on google console and added a server API key, also enabled API Google Cloud Messaging for Android. I have tested with this code (based on this blog post) and, so far, it executes with no errors:

    require 'stella_gcm_xmpp'
    id = '[project_number]@gcm.googleapis.com'
    password = [API_KEY]
    
    gcm = StellaGcmXmpp.new(id, password, true, true)
    gcm.connect
    gcm.callback
    


Upstream Message test

Client Side (out of the scope of the question, for completeness sake):

$ ionic start gcm-test
$ ionic platform add android
$ ionic plugin install cordova-plugin-chrome-apps-gcm 
$ ionic run android

open Chrome-Dev-Tools console:

   > chrome.gcm.register( ['2195xxxxx718'], function(regId) { console.log('regId:' + regId); } )
   > regId:APA91bG_5QIpVrBvuooVp7xO...KiVt3ozcf2HKIkHq_42UAPAU4w
   > chrome.gcm.send( {destinationId: '[email protected]', messageId: '111', timeToLive: 10, data: {my: 'my message'} }, function(messageId) { console.log(messageId); } )
   > 8

Server Side

check receive of upstream message on Ruby (irb) console:

D, [2015-12-18T10:09:05.664007 #4019] DEBUG -- : RECEIVED:
    <message from='[email protected]' to='[email protected]' type='normal'><gcm xmlns='google:mobile:data'>{"data":{"my":"my message"},"time_to_live":86400,"from":"APA91bG_5QIpVrBvuooVp7xOos_EYzA4XNH0CeGzVudbJXxW4avE4NpZO84Q3mC2I-FKAGMTfFdGumSGmkUYViZVwp5gbbC38NDS4GWyaIsABJfhZd3J5KMJBLKgah6lC4LwkbLHKiVt3ozcf2HKIkHq_42UAPAU4w","message_id":"8","category":"com.ionicframework.gcmtest908063"}</gcm></message>
D, [2015-12-18T10:09:05.665623 #4019] DEBUG -- : PROCESSING:
    <message from='[email protected]' to='[email protected]' type='normal' xmlns='jabber:client'><gcm xmlns='google:mobile:data'>{"data":{"my":"my message"},"time_to_live":86400,"from":"APA91bG_5QIpVrBvuooVp7xOos_EYzA4XNH0CeGzVudbJXxW4avE4NpZO84Q3mC2I-FKAGMTfFdGumSGmkUYViZVwp5gbbC38NDS4GWyaIsABJfhZd3J5KMJBLKgah6lC4LwkbLHKiVt3ozcf2HKIkHq_42UAPAU4w","message_id":"8","category":"com.ionicframework.gcmtest908063"}</gcm></message> (Jabber::Message)
D, [2015-12-18T10:09:05.665760 #4019] DEBUG -- : TRYING stanzacbs...
D, [2015-12-18T10:09:05.665859 #4019] DEBUG -- : TRYING message/iq/presence/cbs...
[2015-12-18 10:09:05] GCM send Failed id: 8 error: 

     *The 'GCM send Failed id: 8 error:' occurs not because of an error, but because message-type is empty*

Downstream Message test (out of the scope of the question, for completeness sake)

Client Side

chrome.gcm.onMessage.addListener(function(msg) { console.log('msg: ' + JSON.stringify(msg)) } )

Server Side

gcm.send 'APA91bG_5QIpVrBvuooVp7x...kHq_42UAPAU4w', '999', { msg: 'teste' }

Client Side

msg: {"data":{"msg":"teste"}}

1

1 Answers

0
votes

CCS (GCM's XMPP server) would sit in between your Android clients and your ruby server. Once your ruby server can establish an XMPP connection to CCS then there is nothing special that has to occur to deliver messages from client to server and vice versa. The ruby server would be responsible for sending and receiving messages to and from CCS.