suj-pusher 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +62 -11
- data/bin/pusher +1 -1
- data/lib/suj/pusher.rb +4 -0
- data/lib/suj/pusher/connection_pool.rb +24 -0
- data/lib/suj/pusher/daemon.rb +20 -0
- data/lib/suj/pusher/version.rb +1 -1
- data/lib/suj/pusher/wns_connection.rb +142 -0
- data/lib/suj/pusher/wns_notification.rb +34 -0
- data/lib/suj/pusher/wpns_connection.rb +98 -0
- data/lib/suj/pusher/wpns_notification.rb +34 -0
- metadata +17 -13
data/README.md
CHANGED
@@ -40,24 +40,36 @@ pusher start|stop|restart|status <options>
|
|
40
40
|
```
|
41
41
|
|
42
42
|
options:
|
43
|
-
- -
|
43
|
+
- -H <redis host>: The redis server host or IP address where push messages are stored. Defaults to localhost.
|
44
|
+
- -P <redis port>: Port number of the redis server where push messages are stored. Defaults to 6379.
|
45
|
+
- -b <redis db>: The database number on the redis server to connect to. Defaults to 0.
|
46
|
+
- -n <redis namespace>: A namespace separate pusher queues from others in redis. Defaults to pusher.
|
47
|
+
- -l <logdir>: The directory where logfiles are stored. Defaults to $PWD/logs.
|
48
|
+
- -p <piddir>: The directory where pid files are stored. Defaults to $PWD/pids.
|
49
|
+
- -c <certs>: The directory where we temporarily store APN certs. Defaults to $PWD/certs.
|
44
50
|
|
45
|
-
|
51
|
+
The pusher daemon runs under the current user and current folder. If you specify the logid, piddir and certs folders make sure these exists and that the current user can create/write files inside those folder.
|
52
|
+
|
53
|
+
To start the server run:
|
54
|
+
|
55
|
+
```
|
56
|
+
/path/to/bin/pusher start -H localhost -P 6379 -b 0 -n pusher -p /var/run/pids
|
57
|
+
```
|
58
|
+
|
59
|
+
To stop the server run:
|
46
60
|
|
47
61
|
```
|
48
|
-
|
49
|
-
chown pusher_user:pusher_group /var/run/pusher
|
50
|
-
cd /var/run/pusher
|
51
|
-
/usr/bin/pusher start -r redis://192.168.x.x:6379/namespace
|
62
|
+
/path/to/bin/pusher start -H localhost -P 6379 -b 0 -n pusher -p /var/run/pids
|
52
63
|
```
|
53
64
|
|
54
|
-
|
65
|
+
If you set a piddir (using -p option) when starting the server then you must supply the same option when stopping or restarting the server.
|
66
|
+
|
67
|
+
The certs option (-c) is to temporarily store APN certificates. These are deleted when the APN connection is closed.
|
55
68
|
|
56
69
|
## Sending Notifications
|
57
70
|
|
58
71
|
Once the pusher daemon is running and connected to your redis server you can push notifications by publishing messages to redis. The message format is a simple JSON string.
|
59
72
|
|
60
|
-
|
61
73
|
### JSON string format
|
62
74
|
|
63
75
|
Example JSON message:
|
@@ -107,6 +119,39 @@ Normally you would send messages to either Android or iOS indenpendently. But th
|
|
107
119
|
|
108
120
|
If your data hash is compatible with the APN standard as described above and you specify a APN cert, a GCM api_key, a list of apn_ids and a list of gcm_ids then the message will be delivered via push notification to all the devices in those lists. Apple will display the notifications using their own mechanisms and for Android you will receive the data hash in a Bundle object as usual. Is your responsibility to extract the data from that bundle and display/use it as you please.
|
109
121
|
|
122
|
+
|
123
|
+
|
124
|
+
#### Sending one message to WNS
|
125
|
+
message hash: {
|
126
|
+
wnstype: "type" ,
|
127
|
+
wnsrequeststatus: true,
|
128
|
+
wnsids: ["xxx"],
|
129
|
+
secret: "app-secret",
|
130
|
+
development: false,
|
131
|
+
sid: "secret-id",
|
132
|
+
data: "notif"}
|
133
|
+
wnstype: type of the notification to send, posibles values are: "wns/badge", "wns/tile", "wns/toast", "wns/raw"
|
134
|
+
data: a string with de notifiaction to send, please use the xml templates provided by Microsoft(http://msdn.microsoft.com/en-us/library/windows/apps/hh779725.aspx) for each wnstype listed above.
|
135
|
+
secret and sid: App identification credentials provided by microsoft when registering a new application to use wns services.
|
136
|
+
wnsrequeststatus: boolean, if true, the response from wns server will have aditional information
|
137
|
+
wnsids: jsonArray of target devices.
|
138
|
+
|
139
|
+
|
140
|
+
#### Sending one message to WPNS
|
141
|
+
message hash: { wptype: "type",
|
142
|
+
wpids: ["xxx"],
|
143
|
+
secret: "unicId",
|
144
|
+
development: false,
|
145
|
+
wpnotificationclass: number,
|
146
|
+
data: notif}
|
147
|
+
|
148
|
+
wptype: ype of the notification to send, posible values are: "toast" or "badge", if this parameter is not present, a "raw" type notifications will be sent.
|
149
|
+
secret: a unic hash to identify a conection, internal use, each notification sent must have a diferent id
|
150
|
+
wpids: jsonArray of ids for target devices
|
151
|
+
data: notification data to send, please use de xsml template provided by Microsoft(http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202945(v=vs.105).aspx) for each wptype listed above
|
152
|
+
|
153
|
+
|
154
|
+
|
110
155
|
## Examples
|
111
156
|
|
112
157
|
A simple example using ruby code to send a push notification to iOS devices.
|
@@ -134,20 +179,26 @@ msg_json = MultiJson.dump(msg)
|
|
134
179
|
redis = Redis.new({ host: "localhost", port: 6379})
|
135
180
|
|
136
181
|
# Push the message to the *suj_pusher_queue* in the redis server:
|
137
|
-
redis.lpush "suj_pusher_msgs", msg_json
|
182
|
+
redis.lpush "pusher:suj_pusher_msgs", msg_json
|
138
183
|
|
139
184
|
# Notify workers there is a new message
|
140
|
-
redis.publish "suj_pusher_queue", "PUSH_MSG"
|
185
|
+
redis.publish "pusher:suj_pusher_queue", "PUSH_MSG"
|
141
186
|
```
|
142
187
|
|
143
|
-
|
188
|
+
First you must push your messages to the *suj_pusher_msgs* queue and then publish a *PUSH_MSG* to the *suj_pusher_queue*. The first is a simple queue that stores the messages and the second is a PUB/SUB queue that tells the push daemons that a new message is available. Also make sure to set the same namespace (e.g. pusher) to the queue names that you set on the pusher daemons.
|
144
189
|
|
145
190
|
## Issues
|
146
191
|
|
147
192
|
- We have no feedback mechanism. This is a fire and forget daemon that does not tell us if the message was sent or not.
|
148
193
|
- This daemon has no security at all. Anyone that can push to your redis server can use this daemon to spam your users. Make sure your redis server is only accessible to you and the pusher daemon.
|
149
194
|
|
195
|
+
## Troubleshooting
|
196
|
+
|
197
|
+
- You get errors like "Encryption not available on this event-machine", ensure that the eventmachine gem was installed with ssl support. If you are not sure uninstall the gem, install libssl-dev package and re-install the gem again.
|
198
|
+
- If you get 401 Unauthorized error on the log when sending notifications via GCM, ensure the key you use has configured the global IP addresses of the pusher daemons as allowed.
|
199
|
+
|
150
200
|
## TODO
|
151
201
|
|
152
202
|
- Implement a feedback mechanism that exposes a simple API to allow users check if some tokens, ids, certs, or api_keys are no longer valid so they can take proper action.
|
153
203
|
- Find a way to register certificates and api_key only once so we do not need to send them for every request. Maybe add a cert/key registration api.
|
204
|
+
- For MPNS add ssl service authentification for unlimited push notifications.
|
data/bin/pusher
CHANGED
@@ -37,7 +37,7 @@ ARGV.options do |opts|
|
|
37
37
|
opts.on('-l LOGS', '--logdir LOGS', String, 'Logs destination directory') { |l| logdir = l }
|
38
38
|
opts.on('-p PIDS', '--piddir PIDS', String, 'Pids destination diercoty') { |pid| piddir = pid }
|
39
39
|
opts.on('-c CERTS', '--cerdir CERTS', String, 'Directory to store certificates') { |cert| cerdir = cert }
|
40
|
-
opts.on('-v', '--version', 'Print this version of pusher daemon.') { puts "
|
40
|
+
opts.on('-v', '--version', 'Print this version of pusher daemon.') { puts "Pusher #{Suj::Pusher::VERSION}"; exit }
|
41
41
|
opts.on('-h', '--help', 'You\'re looking at it.') { puts opts; exit }
|
42
42
|
opts.parse!
|
43
43
|
end
|
data/lib/suj/pusher.rb
CHANGED
@@ -7,6 +7,10 @@ require 'suj/pusher/apn_feedback_connection'
|
|
7
7
|
require 'suj/pusher/apn_connection'
|
8
8
|
require 'suj/pusher/gcm_connection'
|
9
9
|
require 'suj/pusher/apn_notification'
|
10
|
+
require 'suj/pusher/wns_connection'
|
11
|
+
require 'suj/pusher/wns_notification'
|
12
|
+
require 'suj/pusher/wpns_connection'
|
13
|
+
require 'suj/pusher/wpns_notification'
|
10
14
|
require 'suj/pusher/daemon'
|
11
15
|
|
12
16
|
require 'logger'
|
@@ -48,6 +48,30 @@ module Suj
|
|
48
48
|
@pool[api_key] ||= Suj::Pusher::GCMConnection.new(self, api_key, options)
|
49
49
|
end
|
50
50
|
|
51
|
+
def apn_connection(options = {})
|
52
|
+
cert = Digest::SHA1.hexdigest options[:cert]
|
53
|
+
info "APN connection #{cert}"
|
54
|
+
@pool[cert] ||= EM.connect(APN_GATEWAY, APN_PORT, APNConnection, self, options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def wns_connection(options = {})
|
58
|
+
cert = Digest::SHA1.hexdigest options[:secret]
|
59
|
+
info "WNS connection #{cert}"
|
60
|
+
info "WNS Options #{options}"
|
61
|
+
@pool[cert] ||= Suj::Pusher::WNSConnection.new(self,options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def wpns_connection(options = {})
|
65
|
+
cert = Digest::SHA1.hexdigest options[:secret]
|
66
|
+
info "WPNS connection #{cert}"
|
67
|
+
info "WPNS Options #{options}"
|
68
|
+
@pool[cert] ||= Suj::Pusher::WPNSConnection.new(self,options)
|
69
|
+
return @pool[cert]
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
51
75
|
def remove_connection(key)
|
52
76
|
info "Removing connection #{key}"
|
53
77
|
info "Connection not found" unless @pool.delete(key)
|
data/lib/suj/pusher/daemon.rb
CHANGED
@@ -81,6 +81,12 @@ module Suj
|
|
81
81
|
end
|
82
82
|
elsif msg.has_key?(:api_key)
|
83
83
|
send_gcm_notification(msg)
|
84
|
+
elsif msg.has_key?(:secret) && msg.has_key?(:sid)
|
85
|
+
#wns push notification
|
86
|
+
send_wns_notification(msg)
|
87
|
+
elsif msg.has_key?(:wpnotificationclass)
|
88
|
+
#send wpns push notification
|
89
|
+
send_wpns_notification(msg)
|
84
90
|
else
|
85
91
|
warn "Could not determine push notification service."
|
86
92
|
end
|
@@ -132,6 +138,20 @@ module Suj
|
|
132
138
|
conn.deliver(msg)
|
133
139
|
end
|
134
140
|
|
141
|
+
def send_wns_notification(msg)
|
142
|
+
info "Sending WNS notification via connection #{Digest::SHA1.hexdigest(msg[:secret])}"
|
143
|
+
conn = pool.wns_connection(msg)
|
144
|
+
conn.deliver(msg)
|
145
|
+
end
|
146
|
+
|
147
|
+
def send_wpns_notification(msg)
|
148
|
+
info "Sending WPNS notification via connection #{Digest::SHA1.hexdigest(msg[:secret])}"
|
149
|
+
conn = pool.wpns_connection(msg)
|
150
|
+
conn.deliver(msg)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
135
155
|
def redis_url
|
136
156
|
@redis_url ||= "redis://#{Suj::Pusher.config.redis_host}:#{Suj::Pusher.config.redis_port}/#{Suj::Pusher.config.redis_db}"
|
137
157
|
end
|
data/lib/suj/pusher/version.rb
CHANGED
@@ -0,0 +1,142 @@
|
|
1
|
+
require "eventmachine"
|
2
|
+
require "em-http"
|
3
|
+
require "base64"
|
4
|
+
require 'uri'
|
5
|
+
module Suj
|
6
|
+
module Pusher
|
7
|
+
class WNSConnection
|
8
|
+
include Suj::Pusher::Logger
|
9
|
+
|
10
|
+
WPN_OAUTH_SERVER = "https://login.live.com/accesstoken.srf"
|
11
|
+
|
12
|
+
ERRORS = {
|
13
|
+
0 => "No errors encountered",
|
14
|
+
1 => "Processing error",
|
15
|
+
2 => "Missing device token",
|
16
|
+
3 => "Missing topic",
|
17
|
+
4 => "Missing payload",
|
18
|
+
5 => "Invalid token size",
|
19
|
+
6 => "Invalid topic size",
|
20
|
+
7 => "Invalid payload size",
|
21
|
+
8 => "Invalid token",
|
22
|
+
255 => "Unknown error"
|
23
|
+
}
|
24
|
+
|
25
|
+
def initialize(pool,options = {})
|
26
|
+
@pool = pool
|
27
|
+
@options = options
|
28
|
+
#info "options #{options}"
|
29
|
+
@cert_key = Digest::SHA1.hexdigest(@options[:secret])
|
30
|
+
@cert_file = File.join(Suj::Pusher.config.certs_path, @cert_key)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
def deliver(options)
|
36
|
+
|
37
|
+
begin
|
38
|
+
@body = "grant_type=client_credentials&client_id=#{CGI.escape(@options[:sid])}&client_secret=#{CGI.escape(@options[:secret])}&scope=notify.windows.com"
|
39
|
+
@header = {"Content-Type" => "application/x-www-form-urlencoded"}
|
40
|
+
http = EventMachine::HttpRequest.new(WPN_OAUTH_SERVER).post( :head => @header, :body =>@body )
|
41
|
+
info http.inspect
|
42
|
+
http.errback do
|
43
|
+
error "WNS network error"
|
44
|
+
@pool.remove_connection(@cert_key)
|
45
|
+
end
|
46
|
+
http.callback do
|
47
|
+
if http.response_header.status != 200
|
48
|
+
error "WNS push error #{http.response_header.status}"
|
49
|
+
error http.response
|
50
|
+
else
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
token = JSON.parse(http.response)
|
55
|
+
@options = options
|
56
|
+
@notification = Suj::Pusher::WnsNotification.new(@options)
|
57
|
+
info "WNS delivering data"
|
58
|
+
@Authorization = "Bearer #{token["access_token"]}"
|
59
|
+
|
60
|
+
@Content_type = ""
|
61
|
+
if(@options[:wnstype].eql?("wns/raw"))
|
62
|
+
|
63
|
+
@Content_type = "application/octet-stream"
|
64
|
+
else
|
65
|
+
|
66
|
+
@Content_type = "text/xml"
|
67
|
+
end
|
68
|
+
@Content_length = @notification.data.size
|
69
|
+
@X_WNS_Type = @options[:wnstype]
|
70
|
+
@X_WNS_Cache_Policy = "no-cache"
|
71
|
+
if(@options.has_key?("wnscache"))
|
72
|
+
|
73
|
+
@X_WNS_Cache_Policy = @options[:wnscache]
|
74
|
+
end
|
75
|
+
@X_WNS_RequestForStatus = true
|
76
|
+
if(@options.has_key?("wnsrequeststatus"))
|
77
|
+
|
78
|
+
@X_WNS_RequestForStatus = @options[:wnsrequeststatus]
|
79
|
+
end
|
80
|
+
@X_WNS_Tag = nil
|
81
|
+
if(@options.has_key?("wnstag"))
|
82
|
+
|
83
|
+
@X_WNS_Tag = @options[:wnstag]
|
84
|
+
end
|
85
|
+
@X_WNS_TTL = nil
|
86
|
+
if(@options.has_key?("time_to_live"))
|
87
|
+
|
88
|
+
@X_WNS_Cache_Policy = @options[:time_to_live]
|
89
|
+
end
|
90
|
+
@options[:wnsids].each do |id|
|
91
|
+
info "atempting send notification to Id: #{id}"
|
92
|
+
@header = Hash.new
|
93
|
+
@header['Authorization'] = @Authorization
|
94
|
+
@header['Content-Type'] = @Content_type
|
95
|
+
@header['Content-Length'] = @Content_length
|
96
|
+
@header['X-WNS-Type'] = @X_WNS_Type
|
97
|
+
@header['X-WNS-Cache-Policy'] = @X_WNS_Cache_Policy
|
98
|
+
@header['X-WNS-RequestForStatus'] = @X_WNS_RequestForStatus
|
99
|
+
if(@X_WNS_Tag!= nil)
|
100
|
+
@header['X-WNS-Tag'] = @X_WNS_Tag
|
101
|
+
end
|
102
|
+
if(@X_WNS_TTL!= nil)
|
103
|
+
@header['X-WNS-TTL'] = @X_WNS_TTL
|
104
|
+
end
|
105
|
+
http2 = EventMachine::HttpRequest.new(id).post( :head => @header, :body =>@options[:data]) #@notification.data )
|
106
|
+
http2.errback do
|
107
|
+
error "WNS-sending network error"
|
108
|
+
end
|
109
|
+
http2.callback do
|
110
|
+
if http2.response_header.status != 200
|
111
|
+
error "WNS-sending push error #{http2.response_header.status}"
|
112
|
+
error http.response
|
113
|
+
else
|
114
|
+
info "WNS-push notification sent"
|
115
|
+
info http2.response_header
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end #nbersano
|
121
|
+
end #nbersano
|
122
|
+
@notification = nil
|
123
|
+
info "WNS delivered data"
|
124
|
+
rescue => ex
|
125
|
+
unbind
|
126
|
+
error "WNS notification error : #{ex}"
|
127
|
+
end
|
128
|
+
unbind
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
def unbind
|
135
|
+
info "WNS Connection closed..."
|
136
|
+
@disconnected = true
|
137
|
+
FileUtils.rm_f(@cert_file)
|
138
|
+
@pool.remove_connection(@cert_key)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Suj
|
2
|
+
module Pusher
|
3
|
+
class WnsNotification
|
4
|
+
include Suj::Pusher::Logger
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def payload
|
12
|
+
@payload ||= MultiJson.dump(@options[:data] || {})
|
13
|
+
end
|
14
|
+
|
15
|
+
def data
|
16
|
+
@data ||= encode_data
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def get_expiry
|
22
|
+
if @ttl.to_i == 0
|
23
|
+
return 0
|
24
|
+
else
|
25
|
+
return Time.now.to_i + @ttl.to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def encode_data
|
30
|
+
Base64.encode64(payload)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "eventmachine"
|
2
|
+
require "em-http"
|
3
|
+
require "base64"
|
4
|
+
require 'uri'
|
5
|
+
module Suj
|
6
|
+
module Pusher
|
7
|
+
class WPNSConnection
|
8
|
+
include Suj::Pusher::Logger
|
9
|
+
|
10
|
+
|
11
|
+
ERRORS = {
|
12
|
+
0 => "No errors encountered",
|
13
|
+
1 => "Processing error",
|
14
|
+
2 => "Missing device token",
|
15
|
+
3 => "Missing topic",
|
16
|
+
4 => "Missing payload",
|
17
|
+
5 => "Invalid token size",
|
18
|
+
6 => "Invalid topic size",
|
19
|
+
7 => "Invalid payload size",
|
20
|
+
8 => "Invalid token",
|
21
|
+
255 => "Unknown error"
|
22
|
+
}
|
23
|
+
|
24
|
+
def initialize(pool,options = {})
|
25
|
+
@pool = pool
|
26
|
+
@options = options
|
27
|
+
@cert_key = Digest::SHA1.hexdigest(@options[:secret])
|
28
|
+
@cert_file = File.join(Suj::Pusher.config.certs_path, @cert_key)
|
29
|
+
info "initialazing wns connection"
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def deliver(options)
|
34
|
+
begin
|
35
|
+
@options = options
|
36
|
+
@notification = Suj::Pusher::WnsNotification.new(@options)
|
37
|
+
info "WPNS delivering data"
|
38
|
+
# @Authorization = "Bearer #{token["access_token"]}"
|
39
|
+
@Content_type = "text/xml; charset=utf-8"
|
40
|
+
@Content_length = @options[:data].size #@notification.data.size
|
41
|
+
@X_MessageID = nil
|
42
|
+
@X_MessageID = @options[:wpmid]
|
43
|
+
@X_WindowsPhone_Target = nil
|
44
|
+
@X_WindowsPhone_Target = @options[:wptype]
|
45
|
+
@X_NotificationClass = @options[:wpnotificationclass]
|
46
|
+
@options[:wpids].each do |id|
|
47
|
+
info "atempting send notification to Id: #{id}"
|
48
|
+
@header = Hash.new
|
49
|
+
@header['Content-Type'] = @Content_type
|
50
|
+
@header['Accept'] = "application/*"
|
51
|
+
# @header['Content-Length'] = @Content_length
|
52
|
+
@header['X-NotificationClass'] = @X_NotificationClass
|
53
|
+
if (@X_WindowsPhone_Target != nil)
|
54
|
+
@header['X-WindowsPhone-Target'] = @X_WindowsPhone_Target
|
55
|
+
else
|
56
|
+
end
|
57
|
+
if( @X_MessageID != nil)
|
58
|
+
@header['X-MessageID'] = @X_MessageID
|
59
|
+
else
|
60
|
+
end
|
61
|
+
http = EventMachine::HttpRequest.new(id).post( :head => @header, :body => @options[:data])# @notification.data )
|
62
|
+
info http.inspect
|
63
|
+
http.errback do
|
64
|
+
error "WPNS-sending network error"
|
65
|
+
end
|
66
|
+
http.callback do
|
67
|
+
if http.response_header.status != 200
|
68
|
+
error "WPNS-sending push error #{http.response_header.status}"
|
69
|
+
error http.response
|
70
|
+
error http.response_header
|
71
|
+
else
|
72
|
+
info "WPNS-push notification sent"
|
73
|
+
info http.response_header
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
@notification = nil
|
80
|
+
info "WPNS delivered data"
|
81
|
+
rescue => ex
|
82
|
+
unbind
|
83
|
+
error "WPNS notification error : #{ex}"
|
84
|
+
end
|
85
|
+
unbind
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
def unbind
|
92
|
+
info "WPNS Connection closed..."
|
93
|
+
FileUtils.rm_f(@cert_file)
|
94
|
+
@pool.remove_connection(@cert_key)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Suj
|
2
|
+
module Pusher
|
3
|
+
class WnpsNotification
|
4
|
+
include Suj::Pusher::Logger
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def payload
|
12
|
+
@payload ||= MultiJson.dump(@options[:data] || {})
|
13
|
+
end
|
14
|
+
|
15
|
+
def data
|
16
|
+
@data ||= encode_data
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def get_expiry
|
22
|
+
if @ttl.to_i == 0
|
23
|
+
return 0
|
24
|
+
else
|
25
|
+
return Time.now.to_i + @ttl.to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def encode_data
|
30
|
+
Base64.encode64(payload)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: suj-pusher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
- Horacio Sanson
|
8
|
+
- Horacio Sanson / Fernando Wong / Nicolas Bersano(WNS and MPNS support)
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: em-http-request
|
16
|
-
requirement: &
|
16
|
+
requirement: &16244860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *16244860
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: em-hiredis
|
27
|
-
requirement: &
|
27
|
+
requirement: &16244440 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *16244440
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: multi_json
|
38
|
-
requirement: &
|
38
|
+
requirement: &16244020 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *16244020
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: daemon-spawn
|
49
|
-
requirement: &
|
49
|
+
requirement: &16243600 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
-
description: Stand alone push notification server for APN and
|
57
|
+
version_requirements: *16243600
|
58
|
+
description: Stand alone push notification server for APN, GCM, WNS and MPNS.
|
59
59
|
email:
|
60
|
-
- rd@skillupjapan.co.jp
|
60
|
+
- rd@skillupjapan.co.jp, n.bersano@skillupchile.cl
|
61
61
|
executables:
|
62
62
|
- pusher
|
63
63
|
extensions: []
|
@@ -76,6 +76,10 @@ files:
|
|
76
76
|
- lib/suj/pusher/logger.rb
|
77
77
|
- lib/suj/pusher/monkey/hash.rb
|
78
78
|
- lib/suj/pusher/version.rb
|
79
|
+
- lib/suj/pusher/wns_connection.rb
|
80
|
+
- lib/suj/pusher/wns_notification.rb
|
81
|
+
- lib/suj/pusher/wpns_connection.rb
|
82
|
+
- lib/suj/pusher/wpns_notification.rb
|
79
83
|
- bin/pusher
|
80
84
|
homepage: https://github.com/sujrd/suj-pusher
|
81
85
|
licenses: []
|