unipush 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/unipush.rb +72 -34
  2. metadata +3 -3
data/lib/unipush.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require 'openssl'
2
+ require 'socket'
3
+ require 'active_support/core_ext'
1
4
  class Unipush
2
- attr_accessor :ios_cert_path
5
+ attr_accessor :ios_cert_path, :ssl, :socket, :ret # пусть к файлу сертификата
3
6
 
4
7
 
5
8
  def initialize(mode='production')
@@ -19,6 +22,12 @@ class Unipush
19
22
  @android_push_url = 'https://android.apis.google.com/c2dm/send'
20
23
 
21
24
  @last_error = []
25
+ @unsent_messages = []
26
+
27
+ @sock = nil
28
+ @ssl = nil
29
+
30
+ @apns_feedback_conn = nil
22
31
  end
23
32
 
24
33
  def get_last_error
@@ -29,8 +38,44 @@ class Unipush
29
38
  @unsent_messages.nil? ? false : @unsent_messages
30
39
  end
31
40
 
41
+ def apns_connect
42
+ cert_path = @ios_cert_path
43
+ if FileTest.exist?(cert_path)
44
+ certificate = File.read(cert_path)
45
+ context = OpenSSL::SSL::SSLContext.new
46
+ context.key = OpenSSL::PKey::RSA.new(certificate)
47
+ context.cert = OpenSSL::X509::Certificate.new(certificate)
48
+ @sock = TCPSocket.new(@ios_push_url, @ios_push_port)
49
+ @ssl = OpenSSL::SSL::SSLSocket.new(@sock, context)
50
+ @ssl.sync = true
51
+ @ssl.connect
52
+ else
53
+ @last_error.push("Certificate file does not exist")
54
+ false
55
+ end
56
+ end
57
+
58
+
59
+ def apns_check_conn
60
+ if @ssl && @sock
61
+ unless @ssl.state == "SSLOK "
62
+ self.apns_connect
63
+ end
64
+ else
65
+ self.apns_connect
66
+ end
67
+ @ssl.state == "SSLOK "
68
+ end
69
+
70
+ def apns_close
71
+ if @ssl
72
+ @ssl.close
73
+ @sock.close
74
+ end
75
+ end
76
+
32
77
  #message={:text=>"", :badge=>0, :newsstand=>true, :track=>true, :add=>{:param1=>1, :param2=>2}}
33
- def prepare_ios_message(token, message)
78
+ def prepare_ios_message(token, message, message_id=0)
34
79
  json = ""
35
80
  if message[:newsstand]
36
81
  json = '{"aps":{"content-available":1}}'
@@ -53,7 +98,7 @@ class Unipush
53
98
 
54
99
  if message[:track]
55
100
  tt = Time.now + 1.day
56
- mes = [1, Random.rand, tt.to_i, 0, 32, token, 0, json.bytesize, json].pack("cNNcca*cca*")
101
+ mes = [1, message_id, tt.to_i, 0, 32, token, 0, json.bytesize, json].pack("cNNcca*cca*")
57
102
  else
58
103
  mes = [0, 0, 32, token, 0, json.bytesize, json].pack("ccca*cca*")
59
104
  end
@@ -64,43 +109,36 @@ class Unipush
64
109
  # messages = [message2, message2, ...]
65
110
  # message=[token, message={:text=>"", :badge=>0, :newsstand=>true, :track=>true, :add=>{:param1=>1, :param2=>2}}]
66
111
  def send_ios_messages(messages)
67
- cert_path = @ios_cert_path
68
- if FileTest.exist?(cert_path)
69
- begin
70
- certificate = File.read(cert_path)
71
- context = OpenSSL::SSL::SSLContext.new
72
- context.key = OpenSSL::PKey::RSA.new(certificate)
73
- context.cert = OpenSSL::X509::Certificate.new(certificate)
74
- socket = TCPSocket.new(@ios_push_url, @ios_push_port)
75
- ssl = OpenSSL::SSL::SSLSocket.new(socket, context)
76
- ssl.sync = true
77
- ssl.connect
78
- messages.each_with_index do |m, k|
79
- mes = prepare_ios_message(m[0], m[1])
80
- if mes
81
- ssl.write(mes)
82
- if ssl.pending >0 && m[1][:track]
83
- tmp = ssl.readline
112
+ begin
113
+ messages.each_with_index do |m, k|
114
+ mes = prepare_ios_message(m[0], m[1], k)
115
+ if mes
116
+ if self.apns_check_conn
117
+ cnt = 0
118
+ @ssl.write(mes)
119
+ begin
120
+ cnt += 1
121
+ tmp = @ssl.read_nonblock(8)
84
122
  reply = tmp.unpack("CCN")
85
- @unsent_messages.push(k)
86
- @last_error.push("Could not send message #{k} width error: "+reply.join(", "))
123
+ @unsent_messages.push(reply[2])
124
+ @last_error.push("Could not send message #{reply[2]} width error: "+reply.join(", "))
125
+ self.apns_close
126
+ break
127
+ rescue IO::WaitReadable
128
+ retry if cnt<1000
87
129
  end
88
- else
89
- @unsent_messages = [] if @unsent_messages.nil?
90
- @unsent_messages.push(k)
130
+ puts k, cnt
91
131
  end
132
+ else
133
+ @unsent_messages = [] if @unsent_messages.nil?
134
+ @unsent_messages.push(k)
92
135
  end
93
- ssl.close
94
- socket.close
95
- rescue
96
- @last_error.push("Could not send messages. Exception: #{$!.inspect}")
97
- false
98
- else
99
- true
100
136
  end
101
- else
102
- @last_error.push("Certificate file does not exist")
137
+ rescue
138
+ @last_error.push("Could not send messages. Exception: #{$!.inspect}")
103
139
  false
140
+ else
141
+ true
104
142
  end
105
143
  end
106
144
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unipush
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-27 00:00:00.000000000 Z
12
+ date: 2013-08-12 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A simple push notification sender for iOS and Android
15
15
  email: alexey.s.kirov@gmail.com
@@ -38,7 +38,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
38
  version: '0'
39
39
  requirements: []
40
40
  rubyforge_project:
41
- rubygems_version: 1.8.11
41
+ rubygems_version: 1.8.23
42
42
  signing_key:
43
43
  specification_version: 3
44
44
  summary: Unipush