hpfeeds 0.1.0 → 0.1.1

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.
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