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 +4 -4
- data/CHANGELOG.md +9 -1
- data/README.md +29 -9
- data/lib/hpfeeds.rb +3 -1
- data/lib/hpfeeds/client.rb +46 -28
- data/lib/hpfeeds/decoder.rb +18 -18
- data/lib/hpfeeds/exception.rb +1 -0
- data/lib/hpfeeds/version.rb +1 -1
- data/lib/hpfeeds/version.rb~ +3 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13f8e72d2ed5ec5e41fd2276f0c81fa308222b6d
|
|
4
|
+
data.tar.gz: e32cf09a6666c6f1f6a9eb4330248d76ac5d2e2b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dbf30ba8497fdc96e278bd44847712d4a7dfcdda6d98f69c9aaaac67c962939a476fccb9d3a18c4837173ad567b0ad3a2f8d4ad82a6c7805cad04b6adceea0ef
|
|
7
|
+
data.tar.gz: 5e9b6dd82041d487cfae67e3fa53f9779714a7a13167957e35defd5b56d654cdef7370b8427765b1c9b55257632966960f7e579db7b75ee21c0fc18480eea519
|
data/CHANGELOG.md
CHANGED
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
33
|
+
STDERR.puts "ERROR: " + data.inspect
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
begin
|
|
37
37
|
@hp = HPFeeds::Client.new ({
|
|
38
|
-
host:
|
|
39
|
-
port: 10000
|
|
40
|
-
ident: '
|
|
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(:
|
|
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
|
data/lib/hpfeeds/client.rb
CHANGED
|
@@ -3,16 +3,16 @@ require 'socket'
|
|
|
3
3
|
|
|
4
4
|
module HPFeeds
|
|
5
5
|
OP_ERROR = 0
|
|
6
|
-
OP_INFO
|
|
7
|
-
OP_AUTH
|
|
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
|
-
|
|
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
|
-
|
|
26
|
+
@stopped = false
|
|
27
27
|
|
|
28
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
70
|
-
|
|
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(
|
|
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.
|
|
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
|
-
|
|
126
|
-
|
|
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
|
-
|
|
136
|
-
|
|
153
|
+
@logger.error(message)
|
|
154
|
+
end
|
|
137
155
|
end
|
|
138
156
|
|
|
139
157
|
private
|
data/lib/hpfeeds/decoder.rb
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
-
|
|
37
|
-
|
|
36
|
+
msg_hdr(OP_SUBSCRIBE, [ident.length].pack("C") + ident + chan)
|
|
37
|
+
end
|
|
38
38
|
|
|
39
39
|
def msg_publish(ident, chan, msg)
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
def msg_hdr(op, data)
|
|
46
|
+
[5+data.length].pack("l>") + [op].pack("C") + data
|
|
47
|
+
end
|
|
48
48
|
end
|
|
49
49
|
end
|
data/lib/hpfeeds/exception.rb
CHANGED
data/lib/hpfeeds/version.rb
CHANGED
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.
|
|
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-
|
|
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
|