hpfeeds 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 03b7575438eb4799c7d0b2e9a25795020f24c501
4
- data.tar.gz: 931209087d6e02e8b34d73d14485e6277747bd46
3
+ metadata.gz: 13f8e72d2ed5ec5e41fd2276f0c81fa308222b6d
4
+ data.tar.gz: e32cf09a6666c6f1f6a9eb4330248d76ac5d2e2b
5
5
  SHA512:
6
- metadata.gz: 24dd1cea9aa0de6f341ecce8a960c1ce8d857b60eb11606458fbbbc7afbcb72164753c86bdfad6daf2f8bb3877f5658c3dda0dec212c2e74366867e0bfed1530
7
- data.tar.gz: a6db74ca3dc4808fbc72208c73a28c729af8d84e27c70e3877c5d306b3368932a0ecaa60adb344e2b8df4c6c2ac3a75a4617c9c660f21704b950c71141beff4c
6
+ metadata.gz: dbf30ba8497fdc96e278bd44847712d4a7dfcdda6d98f69c9aaaac67c962939a476fccb9d3a18c4837173ad567b0ad3a2f8d4ad82a6c7805cad04b6adceea0ef
7
+ data.tar.gz: 5e9b6dd82041d487cfae67e3fa53f9779714a7a13167957e35defd5b56d654cdef7370b8427765b1c9b55257632966960f7e579db7b75ee21c0fc18480eea519
data/CHANGELOG.md CHANGED
@@ -1,2 +1,10 @@
1
- == 0.1.0
1
+ #### 0.1.1
2
+ - major fixes:
3
+ - separate handlers for messages from different chanels
4
+ - better error messages handling
5
+
6
+ - minor fixes:
7
+ - documentation, indentation
8
+
9
+ #### 0.1.0
2
10
  First release
data/README.md CHANGED
@@ -24,25 +24,25 @@ Here is a basic example:
24
24
  require "hpfeeds"
25
25
 
26
26
  def on_data(name, chan, payload)
27
- puts "[%s] %s: %s" % [ chan, name, payload ]
28
- # just an example here...
29
- @hp.publish('channel', 'message')
27
+ puts "[%s] %s: %s" % [ chan, name, payload ]
28
+ # just an example here...
29
+ @hp.publish('channel', 'message')
30
30
  end
31
31
 
32
32
  def on_error(data)
33
- STDERR.puts "ERROR: " + data.inspect
33
+ STDERR.puts "ERROR: " + data.inspect
34
34
  end
35
35
 
36
36
  begin
37
37
  @hp = HPFeeds::Client.new ({
38
- host: hpfeeds_server_name_here,
39
- port: 10000,
40
- ident: 'XXXX',
38
+ host: hpfeeds_server_name_here,
39
+ port: hpfeeds_port_number_here, # default is 10000
40
+ ident: 'XXXXXX',
41
41
  secret: '123456'
42
42
  })
43
43
  channels = %w[ chan1 chan2 chanN ]
44
- @hp.subscribe(*channels)
45
- @hp.run(method(:on_data), method(:on_error))
44
+ @hp.subscribe(*channels) { |name, chan, payload| on_data(name, chan, payload) }
45
+ @hp.run(method(:on_error))
46
46
 
47
47
  rescue => e
48
48
  puts "Exception: #{e}"
@@ -50,6 +50,26 @@ ensure
50
50
  @hp.close if @hp
51
51
  end
52
52
  ```
53
+ ### HPFeeds messages handler
54
+ It's also possibile to set separate handlers for messages from different channels, as follows:
55
+ ```ruby
56
+ @hp.subscribe(chan1, chan2) do
57
+ puts "Received something"
58
+ end
59
+
60
+ @hp.subscribe(chan3, chan4, chan5) do |name, chan|
61
+ puts "Received something on #{chan}, from #{name}"
62
+ end
63
+
64
+ @hp.subscribe(chan6, chan7) { |name, chan, payload| custom_method(name, chan, payload) }
65
+ ```
66
+ ### HPFeeds errors handler
67
+ The argument in
68
+ ```ruby
69
+ @hp.run(method(:on_error))
70
+ ```
71
+ is an handler for HPFeeds error messages (i.e. `'accessfail'` or `'authfail'`).
72
+ It's optional: if you don't provide any handler, an exception will be raised (`HPFeeds::ErrorMessage`) in case of error messages.
53
73
 
54
74
  ## Contributing
55
75
 
data/lib/hpfeeds.rb CHANGED
@@ -2,6 +2,8 @@ require 'hpfeeds/version'
2
2
 
3
3
  module HPFeeds
4
4
  autoload :Client, 'hpfeeds/client'
5
- autoload :Exception, 'hpfeeds/exception'
6
5
  autoload :Decoder, 'hpfeeds/decoder'
6
+ # exceptions
7
+ autoload :Exception, 'hpfeeds/exception'
8
+ autoload :ErrorMessage, 'hpfeeds/exception'
7
9
  end
@@ -3,16 +3,16 @@ require 'socket'
3
3
 
4
4
  module HPFeeds
5
5
  OP_ERROR = 0
6
- OP_INFO = 1
7
- OP_AUTH = 2
6
+ OP_INFO = 1
7
+ OP_AUTH = 2
8
8
  OP_PUBLISH = 3
9
9
  OP_SUBSCRIBE = 4
10
10
 
11
- BUFSIZE = 16384
12
11
  HEADERSIZE = 5
12
+ BUFSIZE = 16384
13
13
 
14
14
  class Client
15
- def initialize(options)
15
+ def initialize(options)
16
16
  @host = options[:host]
17
17
  @port = options[:port] || 10000
18
18
  @ident = options[:ident]
@@ -23,25 +23,27 @@ module HPFeeds
23
23
  @sleepwait = options[:sleepwait] || 20
24
24
 
25
25
  @connected = false
26
- @stopped = false
26
+ @stopped = false
27
27
 
28
- @decoder = Decoder.new
28
+ @decoder = Decoder.new
29
29
  @logger = Logger.new($stdout)
30
30
  @logger.level = Logger::INFO
31
31
 
32
+ @handlers = {}
33
+
32
34
  tryconnect
33
- end
34
-
35
- def tryconnect
36
- loop do
37
- begin
38
- connect()
39
- break
40
- rescue => e
41
- @logger.warn("#{e.class} caugthed while connecting: #{e}. Reconnecting in #{@sleepwait} seconds...")
42
- sleep(@sleepwait)
43
- end
44
- end
35
+ end
36
+
37
+ def tryconnect
38
+ loop do
39
+ begin
40
+ connect()
41
+ break
42
+ rescue => e
43
+ @logger.warn("#{e.class} caugthed while connecting: #{e}. Reconnecting in #{@sleepwait} seconds...")
44
+ sleep(@sleepwait)
45
+ end
46
+ end
45
47
  end
46
48
 
47
49
  def connect
@@ -66,8 +68,8 @@ module HPFeeds
66
68
  @brokername = name
67
69
  auth = @decoder.msg_auth(rand, @ident, @secret)
68
70
  @socket.send(auth, 0)
69
- else
70
- raise Exception('Expected info message at this point.')
71
+ else
72
+ raise Exception.new('Expected info message at this point.')
71
73
  end
72
74
  @logger.info("connected to #{@host}, port #{@port}")
73
75
  @connected = true
@@ -75,11 +77,17 @@ module HPFeeds
75
77
  @socket.setsockopt(Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true))
76
78
  end
77
79
 
78
- def subscribe(*channels)
80
+ def subscribe(*channels, &block)
81
+ if block_given?
82
+ handler = block
83
+ else
84
+ raise ArgumentError.new('When subscribing to a channel, you have to provide a block as a callback for message handling')
85
+ end
79
86
  for c in channels
80
87
  @logger.info("subscribing to #{c}")
81
88
  message = @decoder.msg_subscribe(@ident, c)
82
89
  @socket.send(message, 0)
90
+ @handlers[c] = handler unless handler.nil?
83
91
  end
84
92
  end
85
93
 
@@ -104,7 +112,7 @@ module HPFeeds
104
112
  end
105
113
  end
106
114
 
107
- def run(message_callback, error_callback)
115
+ def run(error_callback = nil)
108
116
  begin
109
117
  while !@stopped
110
118
  while @connected
@@ -118,22 +126,32 @@ module HPFeeds
118
126
  data = @socket.recv(len)
119
127
  @logger.debug("received #{data.length} bytes of data")
120
128
  if opcode == OP_ERROR
121
- error_callback.call(data)
129
+ unless error_callback.nil?
130
+ error_callback.call(data)
131
+ else
132
+ raise ErrorMessage.new(data)
133
+ end
122
134
  elsif opcode == OP_PUBLISH
123
135
  name, chan, payload = @decoder.parse_publish(data)
124
136
  @logger.info("received #{payload.length} bytes of data from #{name} on channel #{chan}")
125
- message_callback.call(name, chan, payload)
126
- end
137
+ handler = @handlers[chan]
138
+ unless handler.nil?
139
+ # ignore unhandled messages
140
+ handler.call(name, chan, payload)
141
+ end
142
+ end
127
143
  end
128
144
  @logger.debug("Lost connection, trying to connect again...")
129
145
  tryconnect
130
146
  end
131
-
147
+ rescue ErrorMessage => e
148
+ @logger.warn("#{e.class} caugthed in main loop: #{e}")
149
+ raise e
132
150
  rescue => e
133
151
  message = "#{e.class} caugthed in main loop: #{e}\n"
134
152
  message += e.backtrace.join("\n")
135
- @logger.error(message)
136
- end
153
+ @logger.error(message)
154
+ end
137
155
  end
138
156
 
139
157
  private
@@ -5,45 +5,45 @@ module HPFeeds
5
5
 
6
6
  def parse_header(header)
7
7
  raise Exception.new("Malformed header") if header.length < 5
8
- len = header[0,4].unpack("l>")[0]
9
- op = header[4,1].unpack("C")[0]
8
+ len = header[0,4].unpack("l>")[0]
9
+ op = header[4,1].unpack("C")[0]
10
10
  return op, len
11
11
  end
12
12
 
13
13
  def parse_info(data)
14
14
  len = data[0,1].unpack("C")[0]
15
15
  raise Exception.new("Malformed data") if data.length <= len
16
- name = data[1,len]
17
- rand = data[(1+len)..-1]
16
+ name = data[1,len]
17
+ rand = data[(1+len)..-1]
18
18
  return name, rand
19
19
  end
20
20
 
21
21
  def parse_publish(data)
22
- len = data[0,1].unpack("C")[0]
23
- name = data[1,len]
24
- len2 = data[(1+len),1].ord
25
- chan = data[(1+len+1),len2]
26
- payload = data[(1+len+1+len2)..-1]
22
+ len = data[0,1].unpack("C")[0]
23
+ name = data[1,len]
24
+ len2 = data[(1+len),1].ord
25
+ chan = data[(1+len+1),len2]
26
+ payload = data[(1+len+1+len2)..-1]
27
27
  return name, chan, payload
28
28
  end
29
29
 
30
30
  def msg_auth(rand, ident, secret)
31
- mac = Digest::SHA1.digest(rand + secret)
32
- msg_hdr(OP_AUTH, [ident.length].pack("C") + ident + mac)
31
+ mac = Digest::SHA1.digest(rand + secret)
32
+ msg_hdr(OP_AUTH, [ident.length].pack("C") + ident + mac)
33
33
  end
34
34
 
35
35
  def msg_subscribe(ident, chan)
36
- msg_hdr(OP_SUBSCRIBE, [ident.length].pack("C") + ident + chan)
37
- end
36
+ msg_hdr(OP_SUBSCRIBE, [ident.length].pack("C") + ident + chan)
37
+ end
38
38
 
39
39
  def msg_publish(ident, chan, msg)
40
- msg_hdr(OP_PUBLISH, [ident.length].pack("C") + ident + [chan.length].pack("C") + chan + msg)
41
- end
40
+ msg_hdr(OP_PUBLISH, [ident.length].pack("C") + ident + [chan.length].pack("C") + chan + msg)
41
+ end
42
42
 
43
43
  private
44
44
 
45
- def msg_hdr(op, data)
46
- [5+data.length].pack("l>") + [op].pack("C") + data
47
- end
45
+ def msg_hdr(op, data)
46
+ [5+data.length].pack("l>") + [op].pack("C") + data
47
+ end
48
48
  end
49
49
  end
@@ -1,3 +1,4 @@
1
1
  module HPFeeds
2
2
  class Exception < RuntimeError; end
3
+ class ErrorMessage < RuntimeError; end
3
4
  end
@@ -1,3 +1,3 @@
1
1
  module HPFeeds
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,3 @@
1
+ module HPFeeds
2
+ VERSION = "0.1.0"
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hpfeeds
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francesco Coda Zabetta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-05 00:00:00.000000000 Z
11
+ date: 2013-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -46,6 +46,7 @@ extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
48
  - lib/hpfeeds/exception.rb
49
+ - lib/hpfeeds/version.rb~
49
50
  - lib/hpfeeds/decoder.rb
50
51
  - lib/hpfeeds/client.rb
51
52
  - lib/hpfeeds/version.rb