roda-websockets 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cb6a87a9451e3df76498a2bb082b0db0905b72e1f4415ead9b86ce96b98decbc
4
+ data.tar.gz: 9838604a59b67df2b16a90c8ab7b78a91ffac5b3c82ee5ef88f609bf05225129
5
+ SHA512:
6
+ metadata.gz: c5c08c73ffbf235a15645f2472cf4ac50cbfc567f12ecb41a05612c21f4c370f9fbbe6f4b3e0f8560fdb0fb2209eb7af13f46270c0e5cd3d5b6412862da04bba
7
+ data.tar.gz: db4e90ad932846bbff3c4e6e74f26c25c648ab2a921f926a3f2722411bf8314e5289b0367f3a272de05fdfbf80a73166fd9ed389b113e46e54f95abd42e05f15
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2019-06-26)
4
+
5
+ * Initial Public Release
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2019 Shannon Skipper
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ # roda-websockets
2
+
3
+ The roda-websockets gem integrates [async-websockets](https://github.com/socketry/async-websocket) into the [roda](http://roda.jeremyevans.net/) web toolkit. Use this plugin for asynchronous websockets alongside roda and falcon.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ gem install roda-websockets
9
+ ```
10
+
11
+ ## Source Code
12
+
13
+ Source code is available on GitHub at
14
+ https://github.com/havenwood/roda-websockets
15
+
16
+ ## Usage
17
+
18
+ roda-websockets requires that you use [Falcon](https://github.com/socketry/falcon) as your web server in order to establish asynchronous websocket connections.
19
+
20
+ ```ruby
21
+ falcon serve --bind http://localhost:3000 --count 1 --config config.ru
22
+ ```
23
+
24
+ roda-websockets is a roda plugin, so you need to load it into your roda
25
+ application similar to other plugins:
26
+
27
+ ```ruby
28
+ class App < Roda
29
+ plugin :websockets
30
+ end
31
+ ```
32
+
33
+ In your routing block, you can use `r.websocket` to pass the routing
34
+ to a websocket connection.
35
+
36
+ ```ruby
37
+ r.websocket do |connection|
38
+ # ...
39
+ end
40
+ ```
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/clean'
5
+ require 'rake/testtask'
6
+
7
+ CLEAN.include %w[pkg/roda-websockets-*.gem].freeze
8
+
9
+ task default: :test
10
+
11
+ Rake::TestTask.new do |test|
12
+ test.pattern = 'spec/**/*_spec.rb'
13
+ test.warning = false
14
+ end
@@ -0,0 +1,64 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'async/websocket/adapters/rack'
4
+
5
+ class Roda
6
+ module RodaPlugins
7
+ # The websockets plugin integrates the async-websocket gem into Roda's
8
+ # routing tree. See the
9
+ # {async-websocket docs}[https://github.com/socketry/async-websocket]
10
+ # for usage details.
11
+ #
12
+ # The following example is an echo server that sleeps one second after
13
+ # receiving a message before echoing that same message back to the client
14
+ # and closing the connection:
15
+ #
16
+ # plugin :websockets
17
+ #
18
+ # def messages(connection)
19
+ # Enumerator.new do |yielder|
20
+ # while (message = connection.read)
21
+ # yielder << message
22
+ # end
23
+ # end
24
+ # end
25
+ #
26
+ # def on_message(connection, message:)
27
+ # Async do |task|
28
+ # task.sleep(1)
29
+ # connection.write(message)
30
+ # connection.flush
31
+ # connection.close
32
+ # end
33
+ # end
34
+ #
35
+ # route do |r|
36
+ # r.root do
37
+ # r.websocket do |connection|
38
+ # messages(connection).each do |message|
39
+ # on_message(connection, message: message)
40
+ # end
41
+ # end
42
+ # end
43
+ # end
44
+ module WebSockets
45
+ module RequestMethods
46
+ ARGS = {}.freeze
47
+
48
+ def websocket?
49
+ Async::WebSocket::Adapters::Rack.websocket?(env)
50
+ end
51
+
52
+ def websocket(args = ARGS, &block)
53
+ return unless websocket?
54
+
55
+ always do
56
+ halt Async::WebSocket::Adapters::Rack.open(env, *args, &block)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ register_plugin(:websockets, WebSockets)
63
+ end
64
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'async'
4
+ require 'async/debug/selector'
5
+ require 'async/http/endpoint'
6
+ require 'async/websocket/client'
7
+ require 'falcon/adapters/rack'
8
+ require 'falcon/server'
9
+ require 'minitest/autorun'
10
+ require 'minitest/pride'
11
+ require 'minitest/proveit'
12
+ require 'roda'
13
+
14
+ describe 'roda-websockets plugin' do
15
+ prove_it!
16
+
17
+ let :reactor do
18
+ Async::Reactor.new(selector: Async::Debug::Selector.new)
19
+ end
20
+
21
+ let :endpoint do
22
+ Async::HTTP::Endpoint.parse('http://localhost:7050')
23
+ end
24
+
25
+ let :app do
26
+ app = Class.new(Roda)
27
+ app.plugin :websockets
28
+ app.route do |r|
29
+ r.root do
30
+ r.websocket do |connection|
31
+ %w[zxc spqr wombat].each do |message|
32
+ connection.write(message)
33
+ connection.flush
34
+ end
35
+
36
+ connection.close
37
+ end
38
+
39
+ 'bar'
40
+ end
41
+ end
42
+
43
+ app
44
+ end
45
+
46
+ let :server do
47
+ Falcon::Server.new(Falcon::Server.middleware(app), endpoint)
48
+ end
49
+
50
+ let :client do
51
+ Async::HTTP::Client.new(endpoint)
52
+ end
53
+
54
+ before do
55
+ @server_task = reactor.async do
56
+ server.run
57
+ end
58
+ end
59
+
60
+ after do
61
+ @server_task.stop
62
+ end
63
+
64
+ it 'supports regular requests' do
65
+ reactor.run do
66
+ response = client.get('/')
67
+ assert_equal response.read, 'bar'
68
+
69
+ client.close
70
+ reactor.stop
71
+ end
72
+ end
73
+
74
+ it 'supports websocket requests' do
75
+ reactor.run do
76
+ Async::WebSocket::Client.connect(endpoint) do |connection|
77
+ assert_equal(connection.read, 'zxc')
78
+ assert_equal(connection.read, 'spqr')
79
+ assert_equal(connection.read, 'wombat')
80
+ end
81
+
82
+ reactor.stop
83
+ end
84
+ end
85
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roda-websockets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Shannon Skipper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: async-websocket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.12'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: falcon
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.33'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.33'
41
+ - !ruby/object:Gem::Dependency
42
+ name: roda
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-proveit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ description: The roda-websockets gem integrates async-websockets into the roda web
84
+ toolkit.
85
+ email: shannonskipper@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - Gemfile
92
+ - LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - lib/roda/plugins/websockets.rb
96
+ - spec/roda-websockets_spec.rb
97
+ homepage: https://github.com/havenwood/roda-websockets
98
+ licenses:
99
+ - MIT
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubygems_version: 3.0.4
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: WebSocket integration for Roda
120
+ test_files: []