sock-drawer 0.0.2
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 +7 -0
- data/.gitignore +43 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +9 -0
- data/lib/sock/client.rb +30 -0
- data/lib/sock/drawer/version.rb +7 -0
- data/lib/sock/drawer.rb +17 -0
- data/lib/sock/server.rb +79 -0
- data/sock-drawer.gemspec +32 -0
- data/spec/client_spec.rb +34 -0
- data/spec/server_spec.rb +137 -0
- data/spec/spec_helper.rb +24 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4aed78bab3749fc12dac0bab025f9677595d9300
|
4
|
+
data.tar.gz: 1ef7a4f58fd5810ee7a9abe707ca5919cae8f882
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c5c7a1b748211288e7b9c265c78baec327483cddbbbc8c40ea81f5e96af6e6187c6f2c962af923b0e89642b5473bd0fe30f83bb0a31f9c43b4b6a628aa8191e4
|
7
|
+
data.tar.gz: 5f90cb1049216f6e32fb69653c807a51e29761d7a08a9604d050f78f87c75439243c183243f64f6ca092f9f6c223caa4b9a1e89ef530fb5d19d69b3721513996
|
data/.gitignore
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/tmp/
|
9
|
+
*.bundle
|
10
|
+
*.so
|
11
|
+
*.o
|
12
|
+
*.a
|
13
|
+
mkmf.log
|
14
|
+
*.gem
|
15
|
+
*.rbc
|
16
|
+
/.config
|
17
|
+
/coverage/
|
18
|
+
/InstalledFiles
|
19
|
+
/pkg/
|
20
|
+
/spec/reports/
|
21
|
+
/test/tmp/
|
22
|
+
/test/version_tmp/
|
23
|
+
/tmp/
|
24
|
+
|
25
|
+
## Documentation cache and generated files:
|
26
|
+
/.yardoc/
|
27
|
+
/_yardoc/
|
28
|
+
/doc/
|
29
|
+
/rdoc/
|
30
|
+
|
31
|
+
## Environment normalisation:
|
32
|
+
/.bundle/
|
33
|
+
/vendor/bundle
|
34
|
+
/lib/bundler/man/
|
35
|
+
|
36
|
+
# for a library or gem, you might want to ignore these files since the code is
|
37
|
+
# intended to run in multiple environments; otherwise, check them in:
|
38
|
+
# Gemfile.lock
|
39
|
+
# .ruby-version
|
40
|
+
# .ruby-gemset
|
41
|
+
|
42
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
43
|
+
.rvmrc
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Adam Hess
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Sock::Drawer
|
2
|
+
|
3
|
+
This gem allows message async message calls to subscribed listeners.
|
4
|
+
Messages can be fired between ruby objects or to listening websocket connections.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'sock-drawer'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install sock-drawer
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Initialize a instance of the sock client
|
25
|
+
|
26
|
+
```Ruby
|
27
|
+
sock = Sock::Client.new(logger: Rails.logger, redis: redis)
|
28
|
+
```
|
29
|
+
|
30
|
+
Publish an event on a channel,
|
31
|
+
|
32
|
+
```Ruby
|
33
|
+
sock.pub("my message", postfix: "my-channel")
|
34
|
+
```
|
35
|
+
|
36
|
+
Subscribe to events fired from a specific sock server,
|
37
|
+
|
38
|
+
```Ruby
|
39
|
+
sock.sub(server, "my-channel") do |message|
|
40
|
+
puts message
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
To capture the event in Javascript use something like,
|
45
|
+
|
46
|
+
```javascript
|
47
|
+
var webSocket = new WebSocket("ws://" + location.hostname + ":8081/" + "my-channel");
|
48
|
+
|
49
|
+
webSocket.onmessage = function(event) {
|
50
|
+
console.log(event.data);
|
51
|
+
}
|
52
|
+
```
|
53
|
+
|
54
|
+
If you wish to start the sock server in another thread you can use
|
55
|
+
|
56
|
+
$ rake sock:server
|
57
|
+
|
58
|
+
And you are good to go!
|
59
|
+
|
60
|
+
## Contributing
|
61
|
+
|
62
|
+
1. Fork it ( https://github.com/[my-github-username]/sock-drawer/fork )
|
63
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
64
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
65
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
66
|
+
5. Create a new Pull Request
|
67
|
+
|
68
|
+
## Running the tests
|
69
|
+
|
70
|
+
if you are going to contribute, I hope you run the tests at least once -- hopefully many times.
|
71
|
+
to run the tests, you must have redis-server running in the background with default configuration.
|
data/Rakefile
ADDED
data/lib/sock/client.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Sock
|
2
|
+
# Client is the interface for publishing events to Drawer
|
3
|
+
class Client
|
4
|
+
def initialize(name: DEFAULT_NAME,
|
5
|
+
logger: Logger.new(STDOUT),
|
6
|
+
redis: Redis.new)
|
7
|
+
@logger = logger
|
8
|
+
@name = name
|
9
|
+
@redis = redis
|
10
|
+
end
|
11
|
+
|
12
|
+
# send a message to all subscribed listeners.
|
13
|
+
def pub(msg, postfix: '')
|
14
|
+
@logger.info "sending #{msg} on channel: #{channel_name(postfix)}"
|
15
|
+
@redis.publish(channel_name(postfix), msg)
|
16
|
+
end
|
17
|
+
|
18
|
+
# subscribe to all events fired on a given channel
|
19
|
+
def sub(server, channel, &block)
|
20
|
+
@logger.info "subscribing to #{channel}"
|
21
|
+
server.channel(channel_name(channel)).subscribe { |msg| block.call(msg) }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def channel_name(postfix)
|
27
|
+
"#{@name}/#{postfix}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/sock/drawer.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'sock/drawer/version'
|
2
|
+
require 'em-websocket'
|
3
|
+
require 'em-hiredis'
|
4
|
+
require 'redis'
|
5
|
+
require 'logger'
|
6
|
+
require 'sock/client'
|
7
|
+
require 'sock/server'
|
8
|
+
|
9
|
+
# Sock is the top level module for sock objects
|
10
|
+
module Sock
|
11
|
+
# the default prefix of events listened to on redis
|
12
|
+
DEFAULT_NAME = 'sock-hook'
|
13
|
+
# the default host to run the websocket server on
|
14
|
+
HOST = '0.0.0.0'
|
15
|
+
# the default port to run the websocket server on.
|
16
|
+
PORT = 8020
|
17
|
+
end
|
data/lib/sock/server.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Sock
|
2
|
+
# server provides a EM process that will manage websocket connections
|
3
|
+
class Server
|
4
|
+
attr_reader :channels, :logger, :name
|
5
|
+
def initialize(name: DEFAULT_NAME,
|
6
|
+
logger: Logger.new(STDOUT),
|
7
|
+
socket_params: { host: HOST, port: PORT },
|
8
|
+
mode: 'default')
|
9
|
+
@name = name
|
10
|
+
@socket_params = socket_params
|
11
|
+
@channels = {}
|
12
|
+
@logger = logger
|
13
|
+
@mode = mode
|
14
|
+
end
|
15
|
+
|
16
|
+
# utility method used to subscribe on the default name and start the socket server
|
17
|
+
def start!
|
18
|
+
EM.run do
|
19
|
+
subscribe(@name)
|
20
|
+
socket_start_listening
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# subscribe fires a event on a EM channel whenever a message is fired on a pattern matching
|
25
|
+
# @name (default: "sock-hook/") + '*'
|
26
|
+
def subscribe(subscription)
|
27
|
+
@logger.info "Subscribing to: #{subscription + '*'}"
|
28
|
+
pubsub.psubscribe(subscription + '*') do |chan, msg|
|
29
|
+
@logger.info "pushing c: #{chan} msg: #{msg}"
|
30
|
+
channel(chan).push(msg)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# channel will find or create a EM channel.
|
35
|
+
# channels can have new events pushed on them or subscribe to events from them.
|
36
|
+
def channel(channel_name)
|
37
|
+
@logger.info "creating channel #{channel_name}" unless @channels[channel_name]
|
38
|
+
@channels[channel_name] ||= EM::Channel.new
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# starts the websocket server
|
43
|
+
# on open this server will find a new channel based on the path
|
44
|
+
# on message it will fire an event to the default 'incoming-hook' channel.
|
45
|
+
# on close, we do nothing. (future direction: would be nice to unsubscribe the websocket event if we know it is the only one listening to that channel)
|
46
|
+
def socket_start_listening
|
47
|
+
EventMachine::WebSocket.start(@socket_params) do |ws|
|
48
|
+
handle_open(ws)
|
49
|
+
handle_message(ws)
|
50
|
+
handle_close(ws)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def handle_open(ws)
|
57
|
+
ws.onopen do |handshake|
|
58
|
+
@logger.info "sock opened on #{handshake.path}"
|
59
|
+
channel(@name + handshake.path).subscribe { |msg| ws.send(msg) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def handle_message(ws)
|
64
|
+
ws.onmessage { |msg| channel('incoming-hook').push(msg) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def handle_close(ws)
|
68
|
+
# TODO: how can I know the sid to remove this subscription?
|
69
|
+
ws.onclose {
|
70
|
+
@logger.info "connection closed"
|
71
|
+
# channel(@name + handshake.path).unsubscribe(sid)
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def pubsub
|
76
|
+
@pubsub ||= EM::Hiredis.connect.pubsub
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/sock-drawer.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sock/drawer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'sock-drawer'
|
8
|
+
spec.version = Sock::Drawer::VERSION
|
9
|
+
spec.authors = ['Adam Hess']
|
10
|
+
spec.email = ['adamhess1991@gmail.com']
|
11
|
+
spec.summary = 'Super simple websocket manager.'
|
12
|
+
spec.description = 'Provide a really simple interface'\
|
13
|
+
'to manage events in ruby and via websockets using ruby and event machine.'
|
14
|
+
spec.homepage = 'http://www.thisisadam.me'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'redis'
|
23
|
+
spec.add_dependency 'eventmachine'
|
24
|
+
spec.add_dependency 'em-hiredis'
|
25
|
+
spec.add_dependency 'em-websocket'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
28
|
+
spec.add_development_dependency 'rspec'
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
+
spec.add_development_dependency 'pry'
|
31
|
+
spec.add_development_dependency 'em-websocket-client'
|
32
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
RSpec.describe Sock::Drawer do
|
5
|
+
let(:redis) { Redis.new }
|
6
|
+
let(:sock) { Sock::Client.new(redis: redis, logger: Logger.new(nil)) }
|
7
|
+
|
8
|
+
context '#pub' do
|
9
|
+
it 'subscribes to events from redis with that name' do
|
10
|
+
expect(redis).to receive(:publish).with('sock-hook/new_channel', 'hi')
|
11
|
+
sock.pub('hi', postfix: 'new_channel')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context '#sub' do
|
16
|
+
let(:server) { Sock::Server.new(logger: Logger.new(nil)) }
|
17
|
+
let(:hi_redis) { EM::Hiredis.connect }
|
18
|
+
|
19
|
+
it 'can register a callback to be run when a event comes through redis' do
|
20
|
+
steps :fire, :received
|
21
|
+
sock.sub(server, 'hi') { |msg|
|
22
|
+
expect(msg).to eq('hi there')
|
23
|
+
complete :received
|
24
|
+
}
|
25
|
+
event_block do
|
26
|
+
server.subscribe(server.name).callback do
|
27
|
+
hi_redis.publish('sock-hook/hi', 'hi there').callback do
|
28
|
+
complete :fire
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'em-websocket-client'
|
3
|
+
|
4
|
+
# TODO rename to server spec
|
5
|
+
|
6
|
+
RSpec.describe Sock::Server do
|
7
|
+
let(:server) { Sock::Server.new(logger: Logger.new(nil)) }
|
8
|
+
let(:redis) { Redis.new }
|
9
|
+
let(:hi_redis) { EM::Hiredis.connect }
|
10
|
+
let(:sock) { Sock::Client.new(redis: redis, logger: Logger.new(nil)) }
|
11
|
+
|
12
|
+
context '#subscribe' do
|
13
|
+
it 'creates a channel for redis events to fire on' do
|
14
|
+
steps :subscribe
|
15
|
+
event_block do
|
16
|
+
df = server.subscribe('my-sub')
|
17
|
+
df.callback { |subs|
|
18
|
+
expect(subs).to eq(1)
|
19
|
+
complete :subscribe
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'pushes an event onto a channel when a redis event is fired' do
|
25
|
+
steps :fire
|
26
|
+
event_block do
|
27
|
+
server.subscribe('my-sub')
|
28
|
+
df = hi_redis.publish('my-sub', 'hello')
|
29
|
+
df.callback {
|
30
|
+
expect(server.channels.keys).to eq(['my-sub'])
|
31
|
+
complete :fire
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'will not create another channel if one already exists' do
|
37
|
+
steps :fire_1, :fire_2
|
38
|
+
event_block do
|
39
|
+
server.subscribe('my-sub')
|
40
|
+
hi_redis.publish('my-sub', 'hello').callback {
|
41
|
+
expect(server.channels.keys).to eq(['my-sub'])
|
42
|
+
complete :fire_1
|
43
|
+
|
44
|
+
hi_redis.publish('my-sub', 'goodbye').callback {
|
45
|
+
expect(server.channels.keys).to eq(['my-sub'])
|
46
|
+
complete :fire_2
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context '#channel' do
|
54
|
+
it 'finds or creates a channel' do
|
55
|
+
server.channel('heyo')
|
56
|
+
expect(server.channels.keys).to eq(['heyo'])
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'prevents duplicates' do
|
60
|
+
server.channel('heyo')
|
61
|
+
server.channel('whatup')
|
62
|
+
expect(server.channels.keys.sort).to eq(['heyo', 'whatup'].sort)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'can have events attached to it' do
|
66
|
+
steps :subscribe
|
67
|
+
event_block do
|
68
|
+
server.channel('9 news').subscribe { |msg|
|
69
|
+
expect(msg).to eq('hello there')
|
70
|
+
complete :subscribe
|
71
|
+
}
|
72
|
+
server.channel('9 news').push("hello there")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context '#socket_start_listening' do
|
78
|
+
let(:conn) { EventMachine::WebSocketClient.connect("ws://0.0.0.0:8020/") }
|
79
|
+
|
80
|
+
it 'subscribes to a channel when a connection opens' do
|
81
|
+
steps :open
|
82
|
+
event_block do
|
83
|
+
server.socket_start_listening
|
84
|
+
EventMachine::WebSocketClient.connect("ws://0.0.0.0:8020/").callback do
|
85
|
+
expect(server.channels.keys).to eq(['sock-hook/'])
|
86
|
+
complete :open
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'opens different channels for different routes' do
|
92
|
+
steps :open
|
93
|
+
event_block do
|
94
|
+
server.socket_start_listening
|
95
|
+
EventMachine::WebSocketClient.connect("ws://0.0.0.0:8020/hi").callback do
|
96
|
+
expect(server.channels.keys).to eq(['sock-hook/hi'])
|
97
|
+
complete :open
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'sends whatever message is sent across the channel' do
|
103
|
+
steps :open, :receive
|
104
|
+
event_block do
|
105
|
+
server.socket_start_listening
|
106
|
+
conn.callback do
|
107
|
+
server.channels['sock-hook/'].push('What up')
|
108
|
+
complete :open
|
109
|
+
end
|
110
|
+
|
111
|
+
conn.stream do |msg|
|
112
|
+
expect(msg.data).to eq('What up')
|
113
|
+
complete :receive
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'will send incoming webhooks to a channel' do
|
119
|
+
steps :open, :receive
|
120
|
+
event_block do
|
121
|
+
server.socket_start_listening
|
122
|
+
conn.callback do
|
123
|
+
conn.send_msg('LGTM')
|
124
|
+
complete :open
|
125
|
+
server.channel('incoming-hook').subscribe { |msg|
|
126
|
+
expect(msg).to eq('LGTM')
|
127
|
+
complete :receive
|
128
|
+
}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'does nothing on close yet' do
|
134
|
+
# TODO: unsub sid
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'sock/drawer'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
def event_block
|
7
|
+
Timeout::timeout(5) do
|
8
|
+
EM.run do
|
9
|
+
EM.epoll
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
end
|
13
|
+
rescue Timeout::Error
|
14
|
+
fail "Eventmachine was not stopped with #{@_em_steps} left"
|
15
|
+
end
|
16
|
+
|
17
|
+
def steps(*steps)
|
18
|
+
@_em_steps = *steps
|
19
|
+
end
|
20
|
+
|
21
|
+
def complete(step)
|
22
|
+
@_em_steps.delete(step)
|
23
|
+
EM.stop if @_em_steps.empty?
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sock-drawer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Hess
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: eventmachine
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: em-hiredis
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: em-websocket
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: em-websocket-client
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Provide a really simple interfaceto manage events in ruby and via websockets
|
140
|
+
using ruby and event machine.
|
141
|
+
email:
|
142
|
+
- adamhess1991@gmail.com
|
143
|
+
executables: []
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".gitignore"
|
148
|
+
- Gemfile
|
149
|
+
- LICENSE.txt
|
150
|
+
- README.md
|
151
|
+
- Rakefile
|
152
|
+
- lib/sock/client.rb
|
153
|
+
- lib/sock/drawer.rb
|
154
|
+
- lib/sock/drawer/version.rb
|
155
|
+
- lib/sock/server.rb
|
156
|
+
- sock-drawer.gemspec
|
157
|
+
- spec/client_spec.rb
|
158
|
+
- spec/server_spec.rb
|
159
|
+
- spec/spec_helper.rb
|
160
|
+
homepage: http://www.thisisadam.me
|
161
|
+
licenses:
|
162
|
+
- MIT
|
163
|
+
metadata: {}
|
164
|
+
post_install_message:
|
165
|
+
rdoc_options: []
|
166
|
+
require_paths:
|
167
|
+
- lib
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
requirements: []
|
179
|
+
rubyforge_project:
|
180
|
+
rubygems_version: 2.2.2
|
181
|
+
signing_key:
|
182
|
+
specification_version: 4
|
183
|
+
summary: Super simple websocket manager.
|
184
|
+
test_files:
|
185
|
+
- spec/client_spec.rb
|
186
|
+
- spec/server_spec.rb
|
187
|
+
- spec/spec_helper.rb
|