message_bus_client 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.hound.yml +2 -0
- data/.idea/message_bus-client.iml +9 -0
- data/.rspec +2 -0
- data/.rubocop.unhound.yml +244 -0
- data/.rubocop.yml +26 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +5 -0
- data/LICENSE +22 -0
- data/README.md +80 -0
- data/Rakefile +33 -0
- data/lib/message_bus_client.rb +39 -0
- data/lib/message_bus_client/client.rb +16 -0
- data/lib/message_bus_client/connection.rb +128 -0
- data/lib/message_bus_client/message_handler.rb +97 -0
- data/lib/message_bus_client/version.rb +3 -0
- data/message_bus_client.gemspec +37 -0
- metadata +219 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7e8175793c25b6e4c0f99e8e742c3fe08da3dd282a8f110eaaa6f2bdd8f5a79e
|
4
|
+
data.tar.gz: ffae4be6e0c5e8f2d68b462f78e86fbb75905116152bf1fc234068824d0dbf47
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 94fcf94075d01bc6b656d2091ae395b00bba4d72a1b0e8aafc3b89f602d1123477ac7d7da2327b5db393bfa5544d2b8a56c3899261e6b3c65d6c8f13351f6d11
|
7
|
+
data.tar.gz: ae8b96a1acfe0b83881610a6535c1383e4d2d137ba1bb778e73361dcd50d32776aae1e765f422f5f2e1eada99ccaba488e1b6f9318df66fab480aad14f47f56c
|
data/.gitignore
ADDED
data/.hound.yml
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
4
|
+
<exclude-output />
|
5
|
+
<content url="file://$MODULE_DIR$" />
|
6
|
+
<orderEntry type="inheritedJdk" />
|
7
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
8
|
+
</component>
|
9
|
+
</module>
|
data/.rspec
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
AccessorMethodName:
|
2
|
+
Enabled: true
|
3
|
+
|
4
|
+
ActionFilter:
|
5
|
+
Enabled: true
|
6
|
+
|
7
|
+
Alias:
|
8
|
+
Enabled: true
|
9
|
+
|
10
|
+
ArrayJoin:
|
11
|
+
Enabled: true
|
12
|
+
|
13
|
+
AsciiComments:
|
14
|
+
Enabled: true
|
15
|
+
|
16
|
+
AsciiIdentifiers:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Attr:
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
BlockNesting:
|
23
|
+
Enabled: true
|
24
|
+
|
25
|
+
CaseEquality:
|
26
|
+
Enabled: true
|
27
|
+
|
28
|
+
CharacterLiteral:
|
29
|
+
Enabled: true
|
30
|
+
|
31
|
+
ClassAndModuleChildren:
|
32
|
+
Enabled: true
|
33
|
+
EnforcedStyle: compact
|
34
|
+
|
35
|
+
ClassLength:
|
36
|
+
Enabled: true
|
37
|
+
|
38
|
+
ClassVars:
|
39
|
+
Enabled: true
|
40
|
+
|
41
|
+
CollectionMethods:
|
42
|
+
Enabled: true
|
43
|
+
PreferredMethods:
|
44
|
+
reduce:
|
45
|
+
inject: 'reduce'
|
46
|
+
find:
|
47
|
+
detect: 'find'
|
48
|
+
|
49
|
+
ColonMethodCall:
|
50
|
+
Enabled: true
|
51
|
+
|
52
|
+
CommentAnnotation:
|
53
|
+
Enabled: true
|
54
|
+
|
55
|
+
CyclomaticComplexity:
|
56
|
+
Enabled: true
|
57
|
+
|
58
|
+
Delegate:
|
59
|
+
Enabled: true
|
60
|
+
|
61
|
+
DeprecatedHashMethods:
|
62
|
+
Enabled: true
|
63
|
+
|
64
|
+
DoubleNegation:
|
65
|
+
Enabled: true
|
66
|
+
|
67
|
+
EachWithObject:
|
68
|
+
Enabled: true
|
69
|
+
|
70
|
+
EmptyLiteral:
|
71
|
+
Enabled: true
|
72
|
+
|
73
|
+
Encoding:
|
74
|
+
Enabled: false
|
75
|
+
|
76
|
+
EvenOdd:
|
77
|
+
Enabled: true
|
78
|
+
|
79
|
+
ExtraSpacing:
|
80
|
+
Enabled: false
|
81
|
+
|
82
|
+
FileName:
|
83
|
+
Enabled: true
|
84
|
+
|
85
|
+
FlipFlop:
|
86
|
+
Enabled: true
|
87
|
+
|
88
|
+
FormatString:
|
89
|
+
Enabled: true
|
90
|
+
|
91
|
+
GlobalVars:
|
92
|
+
Enabled: true
|
93
|
+
|
94
|
+
GuardClause:
|
95
|
+
Enabled: true
|
96
|
+
|
97
|
+
IfUnlessModifier:
|
98
|
+
Enabled: true
|
99
|
+
|
100
|
+
IfWithSemicolon:
|
101
|
+
Enabled: true
|
102
|
+
|
103
|
+
InlineComment:
|
104
|
+
Enabled: false
|
105
|
+
|
106
|
+
Lambda:
|
107
|
+
Enabled: true
|
108
|
+
|
109
|
+
LambdaCall:
|
110
|
+
Enabled: true
|
111
|
+
|
112
|
+
LineEndConcatenation:
|
113
|
+
Enabled: true
|
114
|
+
|
115
|
+
MethodLength:
|
116
|
+
Enabled: true
|
117
|
+
|
118
|
+
ModuleFunction:
|
119
|
+
Enabled: true
|
120
|
+
|
121
|
+
NegatedIf:
|
122
|
+
Enabled: true
|
123
|
+
|
124
|
+
NegatedWhile:
|
125
|
+
Enabled: true
|
126
|
+
|
127
|
+
Next:
|
128
|
+
Enabled: true
|
129
|
+
|
130
|
+
NilComparison:
|
131
|
+
Enabled: true
|
132
|
+
|
133
|
+
Not:
|
134
|
+
Enabled: true
|
135
|
+
|
136
|
+
NumericLiterals:
|
137
|
+
Enabled: true
|
138
|
+
|
139
|
+
OneLineConditional:
|
140
|
+
Enabled: true
|
141
|
+
|
142
|
+
OpMethod:
|
143
|
+
Enabled: true
|
144
|
+
|
145
|
+
ParameterLists:
|
146
|
+
Enabled: true
|
147
|
+
|
148
|
+
PercentLiteralDelimiters:
|
149
|
+
Enabled: true
|
150
|
+
|
151
|
+
PerlBackrefs:
|
152
|
+
Enabled: true
|
153
|
+
|
154
|
+
PredicateName:
|
155
|
+
NamePrefixBlacklist: []
|
156
|
+
|
157
|
+
Proc:
|
158
|
+
Enabled: true
|
159
|
+
|
160
|
+
RaiseArgs:
|
161
|
+
Enabled: true
|
162
|
+
|
163
|
+
RegexpLiteral:
|
164
|
+
Enabled: true
|
165
|
+
|
166
|
+
SelfAssignment:
|
167
|
+
Enabled: true
|
168
|
+
|
169
|
+
SingleLineBlockParams:
|
170
|
+
Enabled: true
|
171
|
+
|
172
|
+
SingleLineMethods:
|
173
|
+
Enabled: true
|
174
|
+
|
175
|
+
SignalException:
|
176
|
+
Enabled: true
|
177
|
+
|
178
|
+
SpecialGlobalVars:
|
179
|
+
Enabled: true
|
180
|
+
|
181
|
+
VariableInterpolation:
|
182
|
+
Enabled: true
|
183
|
+
|
184
|
+
TrailingComma:
|
185
|
+
Enabled: true
|
186
|
+
|
187
|
+
TrivialAccessors:
|
188
|
+
Enabled: true
|
189
|
+
|
190
|
+
VariableInterpolation:
|
191
|
+
Enabled: true
|
192
|
+
|
193
|
+
WhenThen:
|
194
|
+
Enabled: true
|
195
|
+
|
196
|
+
WhileUntilModifier:
|
197
|
+
Enabled: true
|
198
|
+
|
199
|
+
# Lint
|
200
|
+
|
201
|
+
AmbiguousOperator:
|
202
|
+
Enabled: true
|
203
|
+
|
204
|
+
AmbiguousRegexpLiteral:
|
205
|
+
Enabled: true
|
206
|
+
|
207
|
+
AssignmentInCondition:
|
208
|
+
Enabled: true
|
209
|
+
|
210
|
+
ConditionPosition:
|
211
|
+
Enabled: true
|
212
|
+
|
213
|
+
DeprecatedClassMethods:
|
214
|
+
Enabled: true
|
215
|
+
|
216
|
+
ElseLayout:
|
217
|
+
Enabled: true
|
218
|
+
|
219
|
+
HandleExceptions:
|
220
|
+
Enabled: true
|
221
|
+
|
222
|
+
InvalidCharacterLiteral:
|
223
|
+
Enabled: true
|
224
|
+
|
225
|
+
LiteralInCondition:
|
226
|
+
Enabled: true
|
227
|
+
|
228
|
+
LiteralInInterpolation:
|
229
|
+
Enabled: true
|
230
|
+
|
231
|
+
Loop:
|
232
|
+
Enabled: true
|
233
|
+
|
234
|
+
ParenthesesAsGroupedExpression:
|
235
|
+
Enabled: true
|
236
|
+
|
237
|
+
RequireParentheses:
|
238
|
+
Enabled: true
|
239
|
+
|
240
|
+
UnderscorePrefixedVariableName:
|
241
|
+
Enabled: true
|
242
|
+
|
243
|
+
Void:
|
244
|
+
Enabled: true
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
inherit_from:
|
2
|
+
- .rubocop.unhound.yml
|
3
|
+
|
4
|
+
Metrics/LineLength:
|
5
|
+
Max: 100
|
6
|
+
|
7
|
+
Style/DotPosition:
|
8
|
+
EnforcedStyle: trailing
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/IndentHash:
|
14
|
+
EnforcedStyle: consistent
|
15
|
+
|
16
|
+
Style/StringLiterals:
|
17
|
+
EnforcedStyle: single_quotes
|
18
|
+
|
19
|
+
Style/WordArray:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/RegexpLiteral:
|
23
|
+
AllowInnerSlashes: true
|
24
|
+
|
25
|
+
Style/ClassAndModuleChildren:
|
26
|
+
EnforcedStyle: compact
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.0
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [0.2.0] - 2018-07-09
|
8
|
+
### Added
|
9
|
+
- Ability to specify `last_id` of a channel
|
10
|
+
- Get access to `message_id` if specified in the callback
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
- Rename gem to `message_bus_client` to avoid name collisions with `MessageBus` gem
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Joel Low
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# MessageBusClient
|
2
|
+
[![Build Status](https://travis-ci.com/bloom-solutions/message_bus_client.svg?branch=master)](https://travis-ci.com/bloom-solutions/message_bus_client)
|
3
|
+
|
4
|
+
This is a fork of [lowjoel's](https://github.com/lowjoel) [message_bus-client](https://github.com/lowjoel/message_bus-client) with improvements we've been wanting to merge in. Because that repository is no longer active, this gem has been released as `message_bus_client`.
|
5
|
+
|
6
|
+
This is a Ruby implementation of the client for [message_bus](https://github.com/samsaffron/message_bus).
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'message_bus_client'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install message_bus_client
|
23
|
+
|
24
|
+
## Upgrading from `MessageBus::Client`
|
25
|
+
|
26
|
+
1) Change `Gemfile` `gem "message_bus-client"` to `gem "message_bus_client"`
|
27
|
+
2) Change configuration:
|
28
|
+
- `MessageBus.long_polling = true` to `MessageBusClient.configuration.long_polling = true`
|
29
|
+
- `MessageBus.poll_interval = 15` to `MessageBusClient.configuration.poll_interval = 15`
|
30
|
+
- or...
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
MessageBusClient.configure do |c|
|
34
|
+
c.long_polling = true
|
35
|
+
c.poll_interval = 15
|
36
|
+
end
|
37
|
+
```
|
38
|
+
3) Change calls to `MessageBus::Client.new` to `MessageBusClient.new`
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
The API is mostly equivalent with the JavaScript client:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
client = MessageBusClient.new('http://chat.samsaffron.com/')
|
46
|
+
client.subscribe('/message') do |payload, message_id|
|
47
|
+
# Do stuff
|
48
|
+
end
|
49
|
+
|
50
|
+
client.start
|
51
|
+
client.pause
|
52
|
+
client.resume
|
53
|
+
client.stop
|
54
|
+
```
|
55
|
+
|
56
|
+
Both Long Polling and normal polling are supported:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
MessageBusClient.configure do |c|
|
60
|
+
c.long_polling = true # false to disable
|
61
|
+
c.poll_interval = 15 # seconds
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
## Development
|
66
|
+
|
67
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to
|
68
|
+
run the tests.
|
69
|
+
|
70
|
+
If you are running Windows, Ruby is not able to kill the server process. Run it separately using
|
71
|
+
`rake server` before running the specs.
|
72
|
+
|
73
|
+
## Contributing
|
74
|
+
|
75
|
+
Bug reports and pull requests are welcome on GitHub at
|
76
|
+
https://github.com/bloom-solutions/message_bus_client.
|
77
|
+
|
78
|
+
## MIT License
|
79
|
+
|
80
|
+
Released under MIT License.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task :server do
|
7
|
+
pid = 0
|
8
|
+
Bundler.with_clean_env do
|
9
|
+
nul = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'nul' : '/dev/null'
|
10
|
+
pid = spawn "bundle exec puma 'spec/chat_server.ru' 2>#{nul}"
|
11
|
+
end
|
12
|
+
|
13
|
+
at_exit do
|
14
|
+
if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
|
15
|
+
$stderr.puts "Killing pid #{pid}"
|
16
|
+
Process.kill('KILL', pid)
|
17
|
+
Process.wait(pid)
|
18
|
+
else
|
19
|
+
child_pid = `pgrep -P #{pid}`.to_i
|
20
|
+
pids = [child_pid, pid]
|
21
|
+
pids.each do |pid|
|
22
|
+
$stderr.puts "Killing pid #{pid}"
|
23
|
+
Process.kill('KILL', pid)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
sleep 3
|
29
|
+
end
|
30
|
+
|
31
|
+
task :spec => :server
|
32
|
+
|
33
|
+
task default: :spec
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "gem_config"
|
2
|
+
require 'excon'
|
3
|
+
require 'json'
|
4
|
+
require "securerandom"
|
5
|
+
|
6
|
+
require 'message_bus_client/client'
|
7
|
+
require 'message_bus_client/version'
|
8
|
+
|
9
|
+
module MessageBusClient
|
10
|
+
DEFAULT_LONG_POLLING = true
|
11
|
+
DEFAULT_POLL_INTERVAL = 15
|
12
|
+
|
13
|
+
include GemConfig::Base
|
14
|
+
|
15
|
+
with_configuration do
|
16
|
+
has :long_polling, values: [true, false], default: DEFAULT_LONG_POLLING
|
17
|
+
has :poll_interval, classes: Integer, default: DEFAULT_POLL_INTERVAL
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.long_polling
|
21
|
+
self.configuration.long_polling
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.long_polling=(v)
|
25
|
+
self.configuration.long_polling = v
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.poll_interval
|
29
|
+
self.configuration.poll_interval
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.poll_interval=(v)
|
33
|
+
self.configuration.poll_interval = v
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.new(*opts)
|
37
|
+
Client.new(*opts)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'message_bus_client/connection'
|
2
|
+
require 'message_bus_client/message_handler'
|
3
|
+
|
4
|
+
module MessageBusClient
|
5
|
+
class Client
|
6
|
+
|
7
|
+
include MessageBusClient::Connection
|
8
|
+
include MessageBusClient::MessageHandler
|
9
|
+
|
10
|
+
def initialize(base_url)
|
11
|
+
super
|
12
|
+
@client_id = SecureRandom.uuid
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module MessageBusClient::Connection
|
2
|
+
# The connection is in the initialised state.
|
3
|
+
INITIALISED = 0
|
4
|
+
|
5
|
+
# The connection is in the started state.
|
6
|
+
STARTED = 1
|
7
|
+
|
8
|
+
# The connection is in the paused state.
|
9
|
+
PAUSED = 2
|
10
|
+
|
11
|
+
# The connection is in the stopping state.
|
12
|
+
STOPPING = 3
|
13
|
+
|
14
|
+
# The connection is in the stopped state.
|
15
|
+
STOPPED = 4
|
16
|
+
|
17
|
+
def initialize(base_url)
|
18
|
+
@connection = nil
|
19
|
+
@runner = nil
|
20
|
+
@base_url = base_url
|
21
|
+
@state = INITIALISED
|
22
|
+
|
23
|
+
@statistics = { total_calls: 0, failed_calls: 0 }
|
24
|
+
end
|
25
|
+
|
26
|
+
def diagnostics
|
27
|
+
end
|
28
|
+
|
29
|
+
def start
|
30
|
+
return unless @state == INITIALISED || stopped?
|
31
|
+
@state = STARTED
|
32
|
+
|
33
|
+
@connection = Excon.new(server_endpoint, persistent: true)
|
34
|
+
@runner = Thread.new { runner }
|
35
|
+
@runner.abort_on_exception = true
|
36
|
+
end
|
37
|
+
|
38
|
+
def pause
|
39
|
+
return unless @state == STARTED
|
40
|
+
|
41
|
+
@state = PAUSED
|
42
|
+
end
|
43
|
+
|
44
|
+
def paused?
|
45
|
+
@state == PAUSED
|
46
|
+
end
|
47
|
+
|
48
|
+
def resume
|
49
|
+
return unless @state == PAUSED
|
50
|
+
|
51
|
+
@state = STARTED
|
52
|
+
handle_messages
|
53
|
+
end
|
54
|
+
|
55
|
+
def stop
|
56
|
+
return unless @state == STARTED || @state == PAUSED
|
57
|
+
|
58
|
+
@state = STOPPING
|
59
|
+
@connection.reset
|
60
|
+
@runner.join
|
61
|
+
end
|
62
|
+
|
63
|
+
def stopped?
|
64
|
+
@state == STOPPED
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# The runner handling polling over the connection.
|
70
|
+
def runner
|
71
|
+
poll until @state == STOPPING
|
72
|
+
rescue Excon::Errors::Error
|
73
|
+
@statistics[:failed_calls] += 1
|
74
|
+
retry
|
75
|
+
ensure
|
76
|
+
@state = STOPPED
|
77
|
+
end
|
78
|
+
|
79
|
+
# Polls the server for messages.
|
80
|
+
def poll
|
81
|
+
@statistics[:total_calls] += 1
|
82
|
+
|
83
|
+
response = @connection.post(request_parameters)
|
84
|
+
unless MessageBusClient.configuration.long_polling
|
85
|
+
handle_connection_response(response)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# The request parameters when connecting to the server with Excon.
|
90
|
+
def request_parameters
|
91
|
+
request_body = URI.encode_www_form(subscribed_channel_indices.
|
92
|
+
merge(__seq: @statistics[:total_calls]))
|
93
|
+
request_parameters = { body: request_body, headers: headers, read_timeout: 360 }
|
94
|
+
if MessageBusClient.configuration.long_polling
|
95
|
+
request_parameters[:response_block] = method(:handle_chunk).to_proc
|
96
|
+
end
|
97
|
+
|
98
|
+
request_parameters
|
99
|
+
end
|
100
|
+
|
101
|
+
# The headers to send when polling
|
102
|
+
def headers
|
103
|
+
headers = {}
|
104
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
105
|
+
headers['X-SILENCE-LOGGER'] = 'true'
|
106
|
+
unless MessageBusClient.configuration.long_polling
|
107
|
+
headers['Dont-Chunk'] = 'true'
|
108
|
+
end
|
109
|
+
|
110
|
+
headers
|
111
|
+
end
|
112
|
+
|
113
|
+
# Gets the URI to poll the server with
|
114
|
+
def server_endpoint
|
115
|
+
endpoint = "#{@base_url}/message-bus/#{@client_id}/poll"
|
116
|
+
unless MessageBusClient.configuration.long_polling
|
117
|
+
endpoint << "?dlp=t"
|
118
|
+
end
|
119
|
+
|
120
|
+
endpoint
|
121
|
+
end
|
122
|
+
|
123
|
+
# Handles the response from the connection.
|
124
|
+
def handle_connection_response(response)
|
125
|
+
handle_response(response.body)
|
126
|
+
sleep(MessageBusClient.configuration.poll_interval)
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module MessageBusClient::MessageHandler
|
2
|
+
SubscribedChannel = Struct.new(:callbacks, :last_id) do
|
3
|
+
def initialize(last_id)
|
4
|
+
self.callbacks = []
|
5
|
+
self.last_id = last_id
|
6
|
+
end
|
7
|
+
|
8
|
+
def callback(payload, message_id)
|
9
|
+
callbacks.each do |callback|
|
10
|
+
callback.call(payload, message_id)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# The chunk separator for chunked messages.
|
16
|
+
CHUNK_SEPARATOR = "\r\n|\r\n"
|
17
|
+
|
18
|
+
def initialize(base_url)
|
19
|
+
super
|
20
|
+
|
21
|
+
@pending_messages = []
|
22
|
+
@subscribed_channels = {}
|
23
|
+
@payload = String.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def subscribe(channel, last_id=-1, &callback)
|
27
|
+
subscribed_channel = @subscribed_channels[channel]
|
28
|
+
if subscribed_channel.nil?
|
29
|
+
subscribed_channel = @subscribed_channels[channel] =
|
30
|
+
SubscribedChannel.new(last_id)
|
31
|
+
end
|
32
|
+
subscribed_channel.callbacks << callback
|
33
|
+
end
|
34
|
+
|
35
|
+
def unsubscribe
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def subscribed_channel_indices
|
41
|
+
result = {}
|
42
|
+
@subscribed_channels.each do |channel, subscription|
|
43
|
+
result[channel] = subscription.last_id
|
44
|
+
end
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
def handle_chunk(chunk, _remaining_bytes, _total_bytes)
|
50
|
+
@payload << chunk
|
51
|
+
try_consume_message
|
52
|
+
end
|
53
|
+
|
54
|
+
def handle_response(body)
|
55
|
+
handle_messages(JSON.parse(body))
|
56
|
+
end
|
57
|
+
|
58
|
+
def try_consume_message
|
59
|
+
index = @payload.index(CHUNK_SEPARATOR)
|
60
|
+
return unless index
|
61
|
+
|
62
|
+
message = @payload[0..index]
|
63
|
+
@payload = @payload[(index + CHUNK_SEPARATOR.length)..-1]
|
64
|
+
|
65
|
+
handle_response(message)
|
66
|
+
end
|
67
|
+
|
68
|
+
def handle_messages(messages = nil)
|
69
|
+
if paused?
|
70
|
+
@pending_messages.concat(messages)
|
71
|
+
else
|
72
|
+
handle_message_method = method(:handle_message)
|
73
|
+
@pending_messages.each(&handle_message_method)
|
74
|
+
messages.each(&handle_message_method) if messages
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
def handle_message(message)
|
80
|
+
return handle_status_message(message) if message['channel'] == '/__status'
|
81
|
+
|
82
|
+
subscription = @subscribed_channels[message['channel']]
|
83
|
+
return unless subscription
|
84
|
+
|
85
|
+
message_id = message['message_id']
|
86
|
+
subscription.last_id = message_id
|
87
|
+
subscription.callback(message['data'], message_id)
|
88
|
+
end
|
89
|
+
|
90
|
+
def handle_status_message(message)
|
91
|
+
message['data'].each do |channel, last_id|
|
92
|
+
next unless @subscribed_channels.key?(channel)
|
93
|
+
|
94
|
+
@subscribed_channels[channel].last_id = last_id
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'message_bus_client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'message_bus_client'
|
8
|
+
spec.version = MessageBusClient::VERSION
|
9
|
+
spec.authors = ['Joel Low', "Ramon Tayag"]
|
10
|
+
spec.email = ['joel@joelsplace.sg', "ramon.tayag@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = 'Ruby client for Message Bus'
|
13
|
+
spec.description = 'Implements a client for Message Bus, with communication over HTTP'
|
14
|
+
spec.homepage = 'https://github.com/bloom-solutions/message_bus_client'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").
|
18
|
+
reject { |f| f.match(/^(test|spec|features)\//) }
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
spec.add_development_dependency 'simplecov'
|
27
|
+
spec.add_development_dependency 'coveralls'
|
28
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
29
|
+
|
30
|
+
# These dependencies are for running the Chat server locally.
|
31
|
+
spec.add_development_dependency 'message_bus'
|
32
|
+
spec.add_development_dependency 'puma'
|
33
|
+
spec.add_development_dependency 'sinatra'
|
34
|
+
|
35
|
+
spec.add_dependency 'excon', '~> 0.45'
|
36
|
+
spec.add_dependency 'gem_config'
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: message_bus_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joel Low
|
8
|
+
- Ramon Tayag
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-07-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.11'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.11'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: simplecov
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: coveralls
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: codeclimate-test-reporter
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: message_bus
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: puma
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sinatra
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: excon
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0.45'
|
147
|
+
type: :runtime
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0.45'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: gem_config
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
type: :runtime
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
description: Implements a client for Message Bus, with communication over HTTP
|
169
|
+
email:
|
170
|
+
- joel@joelsplace.sg
|
171
|
+
- ramon.tayag@gmail.com
|
172
|
+
executables: []
|
173
|
+
extensions: []
|
174
|
+
extra_rdoc_files: []
|
175
|
+
files:
|
176
|
+
- ".gitignore"
|
177
|
+
- ".hound.yml"
|
178
|
+
- ".idea/message_bus-client.iml"
|
179
|
+
- ".rspec"
|
180
|
+
- ".rubocop.unhound.yml"
|
181
|
+
- ".rubocop.yml"
|
182
|
+
- ".ruby-version"
|
183
|
+
- ".travis.yml"
|
184
|
+
- CHANGELOG.md
|
185
|
+
- Gemfile
|
186
|
+
- LICENSE
|
187
|
+
- README.md
|
188
|
+
- Rakefile
|
189
|
+
- lib/message_bus_client.rb
|
190
|
+
- lib/message_bus_client/client.rb
|
191
|
+
- lib/message_bus_client/connection.rb
|
192
|
+
- lib/message_bus_client/message_handler.rb
|
193
|
+
- lib/message_bus_client/version.rb
|
194
|
+
- message_bus_client.gemspec
|
195
|
+
homepage: https://github.com/bloom-solutions/message_bus_client
|
196
|
+
licenses:
|
197
|
+
- MIT
|
198
|
+
metadata: {}
|
199
|
+
post_install_message:
|
200
|
+
rdoc_options: []
|
201
|
+
require_paths:
|
202
|
+
- lib
|
203
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
|
+
requirements:
|
210
|
+
- - ">="
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
213
|
+
requirements: []
|
214
|
+
rubyforge_project:
|
215
|
+
rubygems_version: 2.7.3
|
216
|
+
signing_key:
|
217
|
+
specification_version: 4
|
218
|
+
summary: Ruby client for Message Bus
|
219
|
+
test_files: []
|