xconn 0.1.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 (97) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +29 -0
  4. data/CHANGELOG.md +5 -0
  5. data/LICENSE +22 -0
  6. data/Makefile +9 -0
  7. data/README.md +2 -0
  8. data/Rakefile +14 -0
  9. data/bin/xconn +79 -0
  10. data/docs/index.md +7 -0
  11. data/docs/installation.md +11 -0
  12. data/example/sample/example.rb +23 -0
  13. data/example/sample/included_app.rb +12 -0
  14. data/lib/tasks/tasks.rake +24 -0
  15. data/lib/wamp/app.rb +39 -0
  16. data/lib/wamp/connection/session.rb +35 -0
  17. data/lib/wamp/connection/stream.rb +68 -0
  18. data/lib/wamp/connection/websocket_client.rb +137 -0
  19. data/lib/wamp/connection/websocket_connection.rb +52 -0
  20. data/lib/wamp/manager/base.rb +41 -0
  21. data/lib/wamp/manager/connection.rb +32 -0
  22. data/lib/wamp/manager/event/abort.rb +21 -0
  23. data/lib/wamp/manager/event/authenticate.rb +14 -0
  24. data/lib/wamp/manager/event/base.rb +41 -0
  25. data/lib/wamp/manager/event/call.rb +40 -0
  26. data/lib/wamp/manager/event/challenge.rb +26 -0
  27. data/lib/wamp/manager/event/error.rb +30 -0
  28. data/lib/wamp/manager/event/event.rb +20 -0
  29. data/lib/wamp/manager/event/goodbye.rb +18 -0
  30. data/lib/wamp/manager/event/hello.rb +38 -0
  31. data/lib/wamp/manager/event/invocation.rb +24 -0
  32. data/lib/wamp/manager/event/publish.rb +22 -0
  33. data/lib/wamp/manager/event/published.rb +13 -0
  34. data/lib/wamp/manager/event/register.rb +30 -0
  35. data/lib/wamp/manager/event/registered.rb +37 -0
  36. data/lib/wamp/manager/event/result.rb +13 -0
  37. data/lib/wamp/manager/event/subscribe.rb +39 -0
  38. data/lib/wamp/manager/event/subscribed.rb +26 -0
  39. data/lib/wamp/manager/event/unregister.rb +19 -0
  40. data/lib/wamp/manager/event/unregistered.rb +13 -0
  41. data/lib/wamp/manager/event/unsubscribe.rb +29 -0
  42. data/lib/wamp/manager/event/unsubscribed.rb +13 -0
  43. data/lib/wamp/manager/event/welcome.rb +21 -0
  44. data/lib/wamp/manager/event/yield.rb +13 -0
  45. data/lib/wamp/manager/event.rb +60 -0
  46. data/lib/wamp/manager/hello_event.rb +263 -0
  47. data/lib/wamp/manager/session.rb +91 -0
  48. data/lib/wamp/manager/subscription.rb +38 -0
  49. data/lib/wamp/manager.rb +12 -0
  50. data/lib/wamp/message_handler/api.rb +67 -0
  51. data/lib/wamp/message_handler/base.rb +65 -0
  52. data/lib/wamp/message_handler/call.rb +14 -0
  53. data/lib/wamp/message_handler/challenge.rb +12 -0
  54. data/lib/wamp/message_handler/error.rb +18 -0
  55. data/lib/wamp/message_handler/event.rb +18 -0
  56. data/lib/wamp/message_handler/goodbye.rb +19 -0
  57. data/lib/wamp/message_handler/hello.rb +18 -0
  58. data/lib/wamp/message_handler/invocation.rb +35 -0
  59. data/lib/wamp/message_handler/publish.rb +14 -0
  60. data/lib/wamp/message_handler/published.rb +18 -0
  61. data/lib/wamp/message_handler/register.rb +14 -0
  62. data/lib/wamp/message_handler/registered.rb +30 -0
  63. data/lib/wamp/message_handler/result.rb +17 -0
  64. data/lib/wamp/message_handler/subscribe.rb +14 -0
  65. data/lib/wamp/message_handler/subscribed.rb +30 -0
  66. data/lib/wamp/message_handler/unregister.rb +14 -0
  67. data/lib/wamp/message_handler/unregistered.rb +32 -0
  68. data/lib/wamp/message_handler/unsubscribe.rb +14 -0
  69. data/lib/wamp/message_handler/unsubscribed.rb +33 -0
  70. data/lib/wamp/message_handler/welcome.rb +12 -0
  71. data/lib/wamp/message_handler.rb +75 -0
  72. data/lib/wamp/router/base.rb +45 -0
  73. data/lib/wamp/router/client.rb +55 -0
  74. data/lib/wamp/router/connection.rb +150 -0
  75. data/lib/wamp/router/realm.rb +92 -0
  76. data/lib/wamp/router/server.rb +83 -0
  77. data/lib/wamp/router.rb +12 -0
  78. data/lib/wamp/serializer/cbor.rb +18 -0
  79. data/lib/wamp/serializer/json.rb +18 -0
  80. data/lib/wamp/serializer/message_pack.rb +18 -0
  81. data/lib/wamp/serializer.rb +5 -0
  82. data/lib/wamp/type/error.rb +24 -0
  83. data/lib/wamp/type/event.rb +16 -0
  84. data/lib/wamp/type/invocation.rb +16 -0
  85. data/lib/wamp/type/publication.rb +14 -0
  86. data/lib/wamp/type/registration.rb +14 -0
  87. data/lib/wamp/type/result.rb +16 -0
  88. data/lib/wamp/type/subscription.rb +14 -0
  89. data/lib/wamp/type/success.rb +8 -0
  90. data/lib/wamp/type.rb +16 -0
  91. data/lib/wamp/version.rb +5 -0
  92. data/lib/wamp.rb +15 -0
  93. data/mkdocs.yml +67 -0
  94. data/sig/wamp/serializer/json.rbs +10 -0
  95. data/sig/wamp.rbs +11 -0
  96. data/wamp.gemspec +40 -0
  97. metadata +223 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f4a4f50da44bd4849d8e503de34fcdee9edf558c06244ec43746b81401c09e3a
4
+ data.tar.gz: 5624eedc589212e83ba1684ab67e06d27bbb14c35dc8cf91245aed67b92475ce
5
+ SHA512:
6
+ metadata.gz: 2867240ea024fafcd2fbc93da161473a546989fe349bc9be61a3e12c209d2358187957f291b0ee9d58874e524139cbfbd567838a4305bde178bb5c7e2519f253
7
+ data.tar.gz: 477e4d9640d8da4e555ace59c5b29f76c7b2b799399c4ad76e17ef9402ca2284519299c4b1e931b18d8e788ba60af7c72300f87819969743e51819fcd9bfb403
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,29 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ NewCops: enable
4
+
5
+ Style/StringLiterals:
6
+ Enabled: true
7
+ EnforcedStyle: double_quotes
8
+
9
+ Style/StringLiteralsInInterpolation:
10
+ Enabled: true
11
+ EnforcedStyle: double_quotes
12
+
13
+ Layout/LineLength:
14
+ Max: 120
15
+
16
+ Metrics/BlockLength:
17
+ Enabled: false
18
+
19
+ Layout/BeginEndAlignment:
20
+ EnforcedStyleAlignWith: start_of_line
21
+
22
+ Layout/EndAlignment:
23
+ EnforcedStyleAlignWith: start_of_line
24
+
25
+ Layout/MultilineMethodCallIndentation:
26
+ EnforcedStyle: indented
27
+
28
+ Layout/CaseIndentation:
29
+ EnforcedStyle: end
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-02-15
4
+
5
+ - Initial release
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Simple Things Inc.
4
+ Copyright (c) 2024 XConnIO Ltd.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
data/Makefile ADDED
@@ -0,0 +1,9 @@
1
+ build-docs:
2
+ mkdir -p site/xconn/
3
+ mkdocs build -d site/xconn/ruby
4
+
5
+ run-docs:
6
+ mkdocs serve
7
+
8
+ clean-docs:
9
+ rm -rf site/
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # wamp.rb
2
+ WAMP v2 Client for Ruby
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
13
+
14
+ Dir.glob("lib/tasks/**/*.rake").each { |r| load r }
data/bin/xconn ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "wamp"
6
+
7
+ require "optparse"
8
+
9
+ options = { host: "127.0.0.1", port: 8080, realm: "realm1", directory: ".", app: "App" }
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: xconn [options]"
12
+
13
+ opts.on("-hHOST", "--host HOST", "WebSocket host (default: ws://127.0.0.1:8080/ws)") do |host|
14
+ options[:host] = host
15
+ end
16
+
17
+ opts.on("-rREALM", "--realm REALM", "Realm (default: reaml1)") do |realm|
18
+ options[:realm] = realm
19
+ end
20
+
21
+ opts.on("-pPORT", "--port PORT", "Port (default: 8080)") do |port|
22
+ options[:port] = port
23
+ end
24
+
25
+ opts.on("-dDIRECTORY", "--directory DIRECTORY", 'Directory (default: ".")') do |directory|
26
+ options[:directory] = directory
27
+ end
28
+
29
+ opts.on("-aAPP", "--app APP", 'App (default: "App")') do |app|
30
+ options[:app] = app
31
+ end
32
+
33
+ opts.on("-v", "--version", "Gem Version") do |version|
34
+ options[:version] = version
35
+ end
36
+ end.parse!
37
+
38
+ if options.include?(:version)
39
+ puts "Xconn v#{Wamp::VERSION}"
40
+ exit 0
41
+ end
42
+
43
+ def create_client_session(router)
44
+ session = Wamp::Connection::Session.new
45
+
46
+ server_session = Wamp::Router::Client.new
47
+ server_session.router = router
48
+ server_session.connection = session
49
+
50
+ session.stream = server_session
51
+ session
52
+ end
53
+
54
+ router = Wamp::Router::Base.new
55
+ router.add_realm(options.fetch(:realm))
56
+
57
+ client = create_client_session(router).tap(&:on_open)
58
+
59
+ begin
60
+ Pathname.new(options[:directory]).glob("**/*.rb").each { |file| require file.to_s }
61
+ rescue LoadError => e
62
+ puts e.message
63
+ exit 1
64
+ end
65
+
66
+ begin
67
+ app = Object.const_get(options[:app])
68
+ app.new.procedures.each do |procedure, func|
69
+ client.api.register(procedure, func) do
70
+ puts "Registered procedure: #{procedure}"
71
+ end
72
+ end
73
+ rescue StandardError => e
74
+ puts e.message
75
+ exit 1
76
+ end
77
+
78
+ server = Wamp::Router::Server.new(router, options)
79
+ server.run
data/docs/index.md ADDED
@@ -0,0 +1,7 @@
1
+ # Overview
2
+ WAMP v2 Client and Router for Ruby.
3
+
4
+ For full documentation visit [XConnIO](https://xconn.io).
5
+
6
+ # Installation
7
+ For installation & usage [xconn-ruby](https://xconn.io/xconn/ruby/installation/).
@@ -0,0 +1,11 @@
1
+ # Installation
2
+ Run this command:
3
+
4
+ ```shell
5
+ gem install xconn
6
+ ```
7
+
8
+ Gemfile
9
+ ```ruby
10
+ gem 'xconn', '~> 0.0.1'
11
+ ```
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "wamp"
4
+ require "date"
5
+ require_relative "included_app"
6
+
7
+ # SystemApp
8
+ class Example < Wamp::App
9
+ register echo: "io.xconn.echo", current_date: "io.xconn.date.get"
10
+
11
+ def initialize
12
+ super
13
+ include_app(IncludedApp.new, "test.")
14
+ end
15
+
16
+ def echo(invocation)
17
+ Wamp::Type::Result.new(args: invocation.args, kwargs: invocation.kwargs, details: invocation.details)
18
+ end
19
+
20
+ def current_date(_invocation)
21
+ Wamp::Type::Result.new(args: Date.today.iso8601)
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "wamp"
4
+
5
+ # Class that can be included
6
+ class IncludedApp < Wamp::App
7
+ register echo: "foo.bar.echo"
8
+
9
+ def echo(invocation)
10
+ Wamp::Type::Result.new(args: invocation.args, kwargs: invocation.kwargs, details: invocation.details)
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :xconn do
4
+ desc "Start SAMPLE app"
5
+ task :run, [:host, :port, :realm, :directory, :app] do |_t, args|
6
+ host = args[:host] || "127.0.0.1"
7
+ port = args[:port] || 8080
8
+ realm = args[:realm] || "realm1"
9
+ app = args[:app] || "Example"
10
+ directory = args[:directory] || "./example/sample"
11
+
12
+ command = "bin/xconn -h #{host} -p #{port} -r #{realm} -d #{directory} -a #{app}"
13
+
14
+ puts "Running: #{command}"
15
+
16
+ trap("SIGINT") do
17
+ puts "\nReceived SIGINT. Gracefully exiting..."
18
+
19
+ exit 0
20
+ end
21
+
22
+ `#{command}`
23
+ end
24
+ end
data/lib/wamp/app.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wamp
4
+ # WAMPApp
5
+ class App
6
+ def initialize
7
+ @procedures = {}
8
+ end
9
+
10
+ def include_app(app, prefix = "")
11
+ if prefix&.length&.zero?
12
+ procedures.merge!(app.procedures)
13
+ else
14
+ app.procedures.each do |procedure, func|
15
+ procedures.merge!({ "#{prefix}#{procedure}" => func })
16
+ end
17
+ end
18
+ end
19
+
20
+ def procedures
21
+ return {} if self.class.procedures && self.class.procedures.empty?
22
+ return @procedures if @procedures.any?
23
+
24
+ self.class.procedures.map do |procedure, registration_name|
25
+ @procedures[registration_name.to_s] = method(procedure)
26
+ end
27
+ @procedures
28
+ end
29
+
30
+ class << self
31
+ attr_reader :procedures
32
+
33
+ def register(procedures = {})
34
+ @procedures ||= {}
35
+ @procedures.merge!(procedures)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wamp
4
+ module Connection
5
+ # Client Session
6
+ class Session
7
+ attr_reader :joiner, :session, :store, :api
8
+ attr_accessor :executor, :stream
9
+
10
+ def initialize(joiner = Wampproto::Joiner.new("realm1"))
11
+ @joiner = joiner
12
+ @session = Wampproto::Session.new(joiner.serializer)
13
+ @api = MessageHandler::Api.new(self)
14
+ @store = {}
15
+ end
16
+
17
+ def on_join(&block)
18
+ self.executor = block
19
+ end
20
+
21
+ def on_open
22
+ stream.on_message joiner.send_hello
23
+ end
24
+
25
+ def on_message(data)
26
+ handler = MessageHandler.resolve(data, self)
27
+ handler.handle
28
+ end
29
+
30
+ def transmit(data)
31
+ stream.on_message data
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nio4r"
4
+
5
+ module Wamp
6
+ module Connection
7
+ # creates actual socket and provides a way to read and write to it
8
+ class Stream
9
+ def initialize(socket_object)
10
+ @socket_object = socket_object
11
+ uri = URI.parse(socket_object.url)
12
+
13
+ @selector = NIO::Selector.new
14
+ @socket = TCPSocket.new(uri.host, uri.port)
15
+ monitor = @selector.register(@socket, :r)
16
+ monitor.value = proc { read_nonblock(monitor.io) }
17
+ end
18
+
19
+ def write(data)
20
+ written = @socket.write_nonblock(data, exception: false)
21
+
22
+ case written
23
+ when :wait_writable
24
+ # procceed
25
+ when data.bytesize
26
+ data.bytesize
27
+ else
28
+ puts [:incomplete_write]
29
+ end
30
+ end
31
+
32
+ def receive(data)
33
+ @socket_object.parse(data)
34
+ end
35
+
36
+ def run
37
+ loop do
38
+ @selector.select { |monitor| monitor.value.call if monitor.readable? }
39
+ break if @closed
40
+ end
41
+ end
42
+
43
+ def read_nonblock(io)
44
+ incoming = io.read_nonblock(4096, exception: false)
45
+
46
+ case incoming
47
+ when :wait_readable
48
+ nil
49
+ when nil
50
+ close
51
+ else
52
+ receive incoming
53
+ end
54
+ end
55
+
56
+ def shutdown
57
+ @selector.deregister(@socket)
58
+ @socket.close
59
+ end
60
+
61
+ def close
62
+ shutdown
63
+ @socket_object.connection_gone
64
+ @closed = true
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "websocket/driver"
4
+ require_relative "stream"
5
+
6
+ module Wamp
7
+ module Connection
8
+ # handles opening connection and providing callbacks when data is avaialble
9
+ class WebsocketClient
10
+ CONNECTING = 0
11
+ OPEN = 1
12
+ CLOSING = 2
13
+ CLOSED = 3
14
+
15
+ attr_reader :url
16
+
17
+ def initialize(event_target, protocols) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
18
+ @event_target = event_target
19
+
20
+ @driver = @driver_started = nil
21
+ @close_params = ["", 1006]
22
+
23
+ @url = event_target.url
24
+ @ready_state = CONNECTING
25
+
26
+ @driver = WebSocket::Driver.client(self, protocols: protocols)
27
+
28
+ @driver.on(:open) { |_e| open }
29
+ @driver.on(:message) { |e| receive_message(e.data) }
30
+ @driver.on(:close) { |e| begin_close(e.reason, e.code) }
31
+ @driver.on(:error) { |e| emit_error(e.message) }
32
+
33
+ @stream = Wamp::Connection::Stream.new(self)
34
+ end
35
+
36
+ def run
37
+ start_driver
38
+ @stream.run
39
+ end
40
+
41
+ def start_driver
42
+ return if @driver_started
43
+
44
+ @driver_started = true
45
+ @driver.start
46
+ end
47
+
48
+ def write(data)
49
+ @stream.write(data)
50
+ rescue StandardError => e
51
+ emit_error(e.message)
52
+ end
53
+
54
+ def transmit(message)
55
+ return false if @ready_state > OPEN
56
+
57
+ case message
58
+ when Numeric then @driver.text(message.to_s)
59
+ when String then @driver.text(message)
60
+ when Array then @driver.binary(message)
61
+ else false
62
+ end
63
+ end
64
+
65
+ def connection_gone
66
+ finalize_close
67
+ end
68
+
69
+ def close(code = nil, reason = nil)
70
+ code ||= 1000
71
+ reason ||= ""
72
+
73
+ unless code == 1000 || (code >= 3000 && code <= 4999)
74
+ raise ArgumentError, "Failed to execute 'close' on WebSocket: " \
75
+ "The code must be either 1000, or between 3000 and 4999. " \
76
+ "#{code} is neither."
77
+ end
78
+
79
+ @ready_state = CLOSING unless @ready_state == CLOSED
80
+ @driver.close(reason, code)
81
+ end
82
+
83
+ def parse(data)
84
+ @driver.parse(data)
85
+ end
86
+
87
+ def alive?
88
+ @ready_state == OPEN
89
+ end
90
+
91
+ # This is populated after successful handeshake
92
+ def protocol
93
+ @driver.protocol
94
+ end
95
+
96
+ private
97
+
98
+ def open
99
+ return unless @ready_state == CONNECTING
100
+
101
+ @ready_state = OPEN
102
+
103
+ @event_target.on_open
104
+ end
105
+
106
+ def receive_message(data)
107
+ return unless @ready_state == OPEN
108
+
109
+ @event_target.on_message(data)
110
+ end
111
+
112
+ def emit_error(message)
113
+ return if @ready_state >= CLOSING
114
+
115
+ @event_target.on_error(message)
116
+ end
117
+
118
+ def begin_close(reason, code)
119
+ return if @ready_state == CLOSED
120
+
121
+ @ready_state = CLOSING
122
+ @close_params = [reason, code]
123
+
124
+ @stream.close
125
+ finalize_close
126
+ end
127
+
128
+ def finalize_close
129
+ return if @ready_state == CLOSED
130
+
131
+ @ready_state = CLOSED
132
+
133
+ @event_target.on_close(*@close_params)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "wampproto"
4
+ require_relative "websocket_client"
5
+
6
+ module Wamp
7
+ module Connection
8
+ # Conn
9
+ class WebSocketConnection < Session
10
+ attr_reader :url, :websocket
11
+
12
+ def initialize(url = "ws://localhost:8080/ws", joiner = Wampproto::Joiner.new("realm1"))
13
+ super(joiner)
14
+ @url = url
15
+ @websocket = Wamp::Connection::WebsocketClient.new(self, protocols)
16
+ end
17
+
18
+ def run
19
+ websocket.run
20
+ ensure
21
+ p %i[run close]
22
+ websocket.close
23
+ end
24
+
25
+ def on_open
26
+ transmit joiner.send_hello
27
+ end
28
+
29
+ def transmit(data)
30
+ websocket.transmit data
31
+ end
32
+
33
+ def on_close(reason, code)
34
+ p [:on_close, reason, code]
35
+ end
36
+
37
+ def on_error; end
38
+
39
+ private
40
+
41
+ def protocols
42
+ case joiner.serializer.name
43
+ when Wampproto::Serializer::JSON.name then "wamp.2.json"
44
+ when Wampproto::Serializer::Msgpack.name then "wamp.2.msgpack"
45
+ when Wampproto::Serializer::Cbor.name then "wamp.2.cbor"
46
+ end.then do |protocol|
47
+ [protocol]
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "event"
4
+ require_relative "subscription"
5
+
6
+ module Wamp
7
+ module Manager
8
+ # no:doc
9
+ class Base
10
+ include WebSocket::Driver::EventEmitter
11
+ attr_reader :session
12
+
13
+ def initialize(options = {})
14
+ super()
15
+ @options = options
16
+ @session = Session.new(self)
17
+ end
18
+
19
+ def transmit(data); end
20
+
21
+ def on_message(message)
22
+ manager = Manager::Event.resolve(message, session)
23
+ manager.emit_event(message)
24
+ end
25
+
26
+ def auth
27
+ @options.fetch(:auth, Auth::Anonymous.new)
28
+ end
29
+
30
+ def run
31
+ message = Message::Hello.new("realm1")
32
+ manager = Manager::Event::Hello.new(message, session)
33
+ manager.add_event_listener # adds on :join event listener
34
+ end
35
+
36
+ def authenticate(challenge)
37
+ auth.authenticate(challenge)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wamp
4
+ module Manager
5
+ # connection
6
+ class Connection < Connection::Base
7
+ attr_reader :session
8
+
9
+ def initialize(*args)
10
+ super
11
+ @session = Session.new(self)
12
+ end
13
+
14
+ def on_message(data)
15
+ message = Message.resolve(coder.decode(data))
16
+ session.on_message(message)
17
+ end
18
+
19
+ def on_open
20
+ send_hello_message
21
+ end
22
+
23
+ private
24
+
25
+ def send_hello_message
26
+ message = Message::Hello.new(@realm, auth.details)
27
+ manager = Manager::Event::Hello.new(message, self)
28
+ manager.add_event_listener # adds on :join event listener
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Wamp
6
+ module Manager
7
+ module Event
8
+ # Abort Message Event
9
+ class Abort < Base
10
+ def emit_event_name
11
+ :close
12
+ end
13
+
14
+ def emit_event(message)
15
+ session.emit(emit_event_name, message)
16
+ session.close(1000, message.reason)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end