async-websocket 0.14.0 → 0.19.0

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/lib/async/websocket/adapters/http.rb +64 -0
  3. data/lib/async/websocket/adapters/rack.rb +11 -28
  4. data/{spec/async/websocket/upgrade.rb → lib/async/websocket/adapters/rails.rb} +20 -19
  5. data/lib/async/websocket/client.rb +19 -13
  6. data/lib/async/websocket/connect_request.rb +4 -0
  7. data/lib/async/websocket/connection.rb +1 -0
  8. data/lib/async/websocket/version.rb +1 -1
  9. metadata +37 -101
  10. data/.editorconfig +0 -6
  11. data/.gitignore +0 -13
  12. data/.rspec +0 -3
  13. data/.travis.yml +0 -21
  14. data/Gemfile +0 -7
  15. data/README.md +0 -143
  16. data/async-websocket.gemspec +0 -29
  17. data/examples/chat/.env +0 -3
  18. data/examples/chat/README.md +0 -147
  19. data/examples/chat/client.rb +0 -32
  20. data/examples/chat/config.ru +0 -150
  21. data/examples/chat/multi-client.rb +0 -79
  22. data/examples/mud/client.rb +0 -34
  23. data/examples/mud/config.ru +0 -142
  24. data/examples/rack/client.rb +0 -19
  25. data/examples/rack/config.ru +0 -12
  26. data/examples/utopia/.bowerrc +0 -4
  27. data/examples/utopia/.gitignore +0 -9
  28. data/examples/utopia/.rspec +0 -4
  29. data/examples/utopia/Gemfile +0 -33
  30. data/examples/utopia/Guardfile +0 -29
  31. data/examples/utopia/README.md +0 -16
  32. data/examples/utopia/Rakefile +0 -8
  33. data/examples/utopia/config.ru +0 -47
  34. data/examples/utopia/config/README.md +0 -7
  35. data/examples/utopia/config/environment.rb +0 -8
  36. data/examples/utopia/lib/readme.txt +0 -1
  37. data/examples/utopia/pages/_heading.xnode +0 -2
  38. data/examples/utopia/pages/_page.xnode +0 -30
  39. data/examples/utopia/pages/client/client.js +0 -28
  40. data/examples/utopia/pages/client/index.xnode +0 -8
  41. data/examples/utopia/pages/errors/exception.xnode +0 -5
  42. data/examples/utopia/pages/errors/file-not-found.xnode +0 -5
  43. data/examples/utopia/pages/links.yaml +0 -2
  44. data/examples/utopia/pages/server/controller.rb +0 -26
  45. data/examples/utopia/public/_static/icon.png +0 -0
  46. data/examples/utopia/public/_static/site.css +0 -205
  47. data/examples/utopia/public/_static/utopia-background.svg +0 -1
  48. data/examples/utopia/public/_static/utopia.svg +0 -1
  49. data/examples/utopia/public/readme.txt +0 -1
  50. data/examples/utopia/spec/spec_helper.rb +0 -31
  51. data/examples/utopia/spec/website_context.rb +0 -11
  52. data/examples/utopia/spec/website_spec.rb +0 -56
  53. data/examples/utopia/tasks/bower.rake +0 -45
  54. data/examples/utopia/tasks/deploy.rake +0 -13
  55. data/examples/utopia/tasks/development.rake +0 -34
  56. data/examples/utopia/tasks/environment.rake +0 -17
  57. data/examples/utopia/tasks/log.rake +0 -17
  58. data/examples/utopia/tasks/static.rake +0 -43
  59. data/spec/async/websocket/adapters/rack/client.rb +0 -38
  60. data/spec/async/websocket/adapters/rack/config.ru +0 -23
  61. data/spec/async/websocket/adapters/rack_spec.rb +0 -84
  62. data/spec/async/websocket/connection_spec.rb +0 -34
  63. data/spec/async/websocket/server_examples.rb +0 -117
  64. data/spec/async/websocket/server_spec.rb +0 -31
  65. data/spec/spec_helper.rb +0 -16
@@ -1,79 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'async'
4
- require 'async/semaphore'
5
- require 'async/clock'
6
- require 'async/io/stream'
7
- require 'async/http/endpoint'
8
- require_relative '../../lib/async/websocket/client'
9
-
10
- require 'samovar'
11
-
12
- GC.disable
13
-
14
- class Command < Samovar::Command
15
- options do
16
- option "-c/--count <integer>", "The total number of connections to make.", default: 1000, type: Integer
17
- option "--bind <address>", "The local address to bind to before making a connection."
18
- option "--connect <string>", "The remote server to connect to.", default: "https://localhost:8080"
19
-
20
- option "-s/--semaphore <integer>", "The number of simultaneous connections to perform."
21
- end
22
-
23
- def local_address
24
- if bind = @options[:bind]
25
- Async::IO::Address.tcp(bind, 0)
26
- end
27
- end
28
-
29
- def call
30
- endpoint = Async::HTTP::Endpoint.parse(@options[:connect])
31
- # endpoint = endpoint.each.first
32
-
33
- count = @options[:count]
34
-
35
- connections = Async::Queue.new
36
-
37
- Async do |task|
38
- task.logger.info!
39
-
40
- task.async do |subtask|
41
- while connection = connections.dequeue
42
- subtask.async(connection) do |subtask, connection|
43
- while message = connection.read
44
- puts "> #{message.inspect}"
45
- end
46
- ensure
47
- connection.close
48
- end
49
- end
50
-
51
- GC.start
52
- end
53
-
54
- client = Async::WebSocket::Client.open(endpoint)
55
- start_time = Async::Clock.now
56
-
57
- count.times do |i|
58
- connections.enqueue(client.connect(endpoint.path))
59
-
60
- if (i % 10000).zero?
61
- count = i+1
62
- duration = Async::Clock.now - start_time
63
- Async.logger.info(self) {"Made #{count} connections: #{(count/duration).round(2)} connections/second..."}
64
- end
65
-
66
- if (i % 10000).zero?
67
- duration = Async::Clock.measure{GC.start(full_mark: false, immediate_sweep: false)}
68
- Async.logger.info(self) {"GC.start duration=#{duration.round(2)}s GC.count=#{GC.count}"}
69
- end
70
- end
71
-
72
- connections.enqueue(nil)
73
-
74
- Async.logger.info(self) {"Finished top level connection loop..."}
75
- end
76
- end
77
- end
78
-
79
- Command.call
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'async'
4
- require 'async/io/stream'
5
- require 'async/http/endpoint'
6
- require 'async/websocket/client'
7
-
8
- USER = ARGV.pop || "anonymous"
9
- URL = ARGV.pop || "http://127.0.0.1:7070"
10
-
11
- Async do |task|
12
- stdin = Async::IO::Stream.new(
13
- Async::IO::Generic.new($stdin)
14
- )
15
-
16
- endpoint = Async::HTTP::Endpoint.parse(URL)
17
-
18
- Async::WebSocket::Client.connect(endpoint) do |connection|
19
- task.async do
20
- $stdout.write "> "
21
-
22
- while line = stdin.read_until("\n")
23
- connection.write({input: line})
24
- connection.flush
25
-
26
- $stdout.write "> "
27
- end
28
- end
29
-
30
- while message = connection.read
31
- $stdout.puts message
32
- end
33
- end
34
- end
@@ -1,142 +0,0 @@
1
- #!/usr/bin/env -S falcon serve --count 1 --bind http://127.0.0.1:7070 -c
2
-
3
- require 'async/websocket/adapters/rack'
4
-
5
- class Room
6
- def initialize(name, description = nil)
7
- @name = name
8
- @description = description
9
-
10
- @actions = {}
11
- @users = []
12
- end
13
-
14
- attr :name
15
- attr :description
16
-
17
- attr :actions
18
-
19
- def connect(key, room)
20
- @actions[key] = lambda do |user|
21
- self.exit(user)
22
- room.enter(user)
23
- end
24
-
25
- return room
26
- end
27
-
28
- def broadcast(message)
29
- @users.each do |user|
30
- user.write(message)
31
- user.flush
32
- end
33
- end
34
-
35
- def enter(user)
36
- user.notify("You have entered the #{@name}.")
37
- user.room = self
38
-
39
- @users << user
40
-
41
- @users.each do |user|
42
- user.notify("#{user.name} entered the room.")
43
- end
44
- end
45
-
46
- def exit(user)
47
- if @users.delete(user)
48
- @users.each do |user|
49
- user.notify("#{user.name} left the room.")
50
- end
51
- end
52
- end
53
-
54
- def as_json
55
- {
56
- name: @name,
57
- description: @description,
58
- actions: @actions.keys,
59
- }
60
- end
61
- end
62
-
63
- module Command
64
- def self.split(line)
65
- line.scan(/(?:"")|(?:"(.*[^\\])")|(\w+)/).flatten.compact
66
- end
67
- end
68
-
69
- class User < Async::WebSocket::Connection
70
- def initialize(*)
71
- super
72
-
73
- @name = name
74
- @room = nil
75
- @inventory = []
76
- end
77
-
78
- attr_accessor :room
79
-
80
- ANONYMOUS = "Anonymous"
81
-
82
- def name
83
- @name || ANONYMOUS
84
- end
85
-
86
- def handle(message)
87
- key, *arguments = Command.split(message[:input])
88
- case key
89
- when "name"
90
- @name = arguments.first
91
- when "look"
92
- self.write({room: @room.as_json})
93
- else
94
- if action = @room.actions[key]
95
- action.call(self, *arguments)
96
- else
97
- message[:user]
98
- @room.broadcast(message)
99
- end
100
- end
101
- end
102
-
103
- def notify(text)
104
- self.write({notify: text})
105
- self.flush
106
- end
107
-
108
- def close
109
- if @room
110
- @room.exit(self)
111
- end
112
-
113
- super
114
- end
115
- end
116
-
117
- class Server
118
- def initialize(app)
119
- @app = app
120
-
121
- @entrance = Room.new("Portal", "A vast entrance foyer with a flowing portal.")
122
- @entrance.connect("forward", Room.new("Training Room"))
123
- @entrance.connect("corridor", Room.new("Shop"))
124
- end
125
-
126
- def call(env)
127
- Async::WebSocket::Adapters::Rack.open(env, handler: User) do |user|
128
- @entrance.enter(user)
129
-
130
- while message = user.read
131
- user.handle(message)
132
- end
133
- ensure
134
- # Async.logger.error(self, $!) if $!
135
- user.close
136
- end or @app.call(env)
137
- end
138
- end
139
-
140
- use Server
141
-
142
- run lambda {|env| [200, {}, []]}
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'async'
4
- require 'async/http/endpoint'
5
- require 'async/websocket/client'
6
-
7
- URL = ARGV.pop || "http://127.0.0.1:7070"
8
-
9
- Async do |task|
10
- endpoint = Async::HTTP::Endpoint.parse(URL)
11
-
12
- Async::WebSocket::Client.connect(endpoint) do |connection|
13
- connection.write ["Hello", "World"]
14
-
15
- while message = connection.read
16
- p message
17
- end
18
- end
19
- end
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env -S falcon serve --bind http://127.0.0.1:7070 --count 1 -c
2
-
3
- require 'async/websocket/adapters/rack'
4
-
5
- app = lambda do |env|
6
- Async::WebSocket::Adapters::Rack.open(env) do |connection|
7
- message = connection.read
8
- connection.write message.reverse
9
- end
10
- end
11
-
12
- run app
@@ -1,4 +0,0 @@
1
- {
2
- "directory": "lib/components",
3
- "public": "public/_components"
4
- }
@@ -1,9 +0,0 @@
1
- # Development specific:
2
- .rspec_status
3
- .tags*
4
-
5
- # Temporary data should not be added to the repository:
6
- tmp/
7
-
8
- # This file should only ever exist on production, and may contain sensitive information:
9
- config/environment.yaml
@@ -1,4 +0,0 @@
1
- --format documentation
2
- --backtrace
3
- --warnings
4
- --require spec_helper
@@ -1,33 +0,0 @@
1
-
2
- source "https://rubygems.org"
3
-
4
- gem "utopia", "~> 2.9.3"
5
-
6
- gem "rake"
7
- gem "bundler"
8
-
9
- gem 'async-websocket'
10
-
11
- gem "rack-freeze", "~> 1.2"
12
-
13
- group :development do
14
- # For `rake server`:
15
- gem "guard-falcon", require: false
16
- gem 'guard-rspec', require: false
17
-
18
- # For `rake console`:
19
- gem "pry"
20
- gem "rack-test"
21
-
22
- # For `rspec` testing:
23
- gem "rspec"
24
- gem "simplecov"
25
-
26
- # For testing:
27
- gem 'async-rspec'
28
- end
29
-
30
- group :production do
31
- # Used for passenger-config to restart server after deployment:
32
- gem "passenger"
33
- end
@@ -1,29 +0,0 @@
1
-
2
- group :development do
3
- guard :falcon, port: 9292 do
4
- watch('Gemfile.lock')
5
- watch('config.ru')
6
- watch(%r{^config|lib|pages/.*})
7
-
8
- notification :off
9
- end
10
- end
11
-
12
- group :test do
13
- guard :rspec, cmd: 'rspec' do
14
- # Notifications can get a bit tedious:
15
- # notification :off
16
-
17
- # Re-run specs if they are changed:
18
- watch(%r{^spec/.+_spec\.rb$})
19
- watch('spec/spec_helper.rb') {'spec'}
20
-
21
- # Run relevent specs if files in `lib/` or `pages/` are changed:
22
- watch(%r{^lib/(.+)\.rb$}) {|match| "spec/lib/#{match[1]}_spec.rb" }
23
- watch(%r{^pages/(.+)\.(rb|xnode)$}) {|match| "spec/pages/#{match[1]}_spec.rb"}
24
- watch(%r{^pages/(.+)controller\.rb$}) {|match| Dir.glob("spec/pages/#{match[1]}*_spec.rb")}
25
-
26
- # If any files in pages changes, ensure the website still works:
27
- watch(%r{^pages/.*}) {'spec/website_spec.rb'}
28
- end
29
- end
@@ -1,16 +0,0 @@
1
- # Example WebSocket Chat Server
2
-
3
- This is a simple chat client/server implementation with specs.
4
-
5
- ## Starting Development Server
6
-
7
- To start the development server, simply execute
8
-
9
- > rake
10
- Generating transient session key for development...
11
- 20:57:36 - INFO - Starting Falcon HTTP server on localhost:9292
12
- 20:57:36 - INFO - Guard::RSpec is running
13
- 20:57:36 - INFO - Guard is now watching at '...'
14
- [1] guard(main)>
15
-
16
- Then browse http://localhost:9292 (or as specified) to see your new site.
@@ -1,8 +0,0 @@
1
-
2
- require 'pathname'
3
- SITE_ROOT = Pathname.new(__dir__).realpath
4
-
5
- # Load all rake tasks:
6
- import(*Dir.glob('tasks/**/*.rake'))
7
-
8
- task :default => :development
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env rackup
2
-
3
- require_relative 'config/environment'
4
-
5
- require 'rack/freeze'
6
-
7
- if RACK_ENV == :production
8
- # Handle exceptions in production with a error page and send an email notification:
9
- use Utopia::Exceptions::Handler
10
- use Utopia::Exceptions::Mailer
11
- else
12
- # We want to propate exceptions up when running tests:
13
- use Rack::ShowExceptions unless RACK_ENV == :test
14
-
15
- # Serve the public directory in a similar way to the web server:
16
- use Utopia::Static, root: 'public'
17
- end
18
-
19
- use Rack::Sendfile
20
-
21
- use Utopia::ContentLength
22
-
23
- use Utopia::Redirection::Rewrite,
24
- '/' => '/client/index'
25
-
26
- use Utopia::Redirection::DirectoryIndex
27
-
28
- use Utopia::Redirection::Errors,
29
- 404 => '/errors/file-not-found'
30
-
31
- use Utopia::Localization,
32
- :default_locale => 'en',
33
- :locales => ['en', 'de', 'ja', 'zh']
34
-
35
- require 'utopia/session'
36
- use Utopia::Session,
37
- :expires_after => 3600 * 24,
38
- :secret => ENV['UTOPIA_SESSION_SECRET']
39
-
40
- use Utopia::Controller
41
-
42
- use Utopia::Static
43
-
44
- # Serve dynamic content
45
- use Utopia::Content
46
-
47
- run lambda { |env| [404, {}, []] }