xconn 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +29 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +22 -0
- data/Makefile +9 -0
- data/README.md +2 -0
- data/Rakefile +14 -0
- data/bin/xconn +79 -0
- data/docs/index.md +7 -0
- data/docs/installation.md +11 -0
- data/example/sample/example.rb +23 -0
- data/example/sample/included_app.rb +12 -0
- data/lib/tasks/tasks.rake +24 -0
- data/lib/wamp/app.rb +39 -0
- data/lib/wamp/connection/session.rb +35 -0
- data/lib/wamp/connection/stream.rb +68 -0
- data/lib/wamp/connection/websocket_client.rb +137 -0
- data/lib/wamp/connection/websocket_connection.rb +52 -0
- data/lib/wamp/manager/base.rb +41 -0
- data/lib/wamp/manager/connection.rb +32 -0
- data/lib/wamp/manager/event/abort.rb +21 -0
- data/lib/wamp/manager/event/authenticate.rb +14 -0
- data/lib/wamp/manager/event/base.rb +41 -0
- data/lib/wamp/manager/event/call.rb +40 -0
- data/lib/wamp/manager/event/challenge.rb +26 -0
- data/lib/wamp/manager/event/error.rb +30 -0
- data/lib/wamp/manager/event/event.rb +20 -0
- data/lib/wamp/manager/event/goodbye.rb +18 -0
- data/lib/wamp/manager/event/hello.rb +38 -0
- data/lib/wamp/manager/event/invocation.rb +24 -0
- data/lib/wamp/manager/event/publish.rb +22 -0
- data/lib/wamp/manager/event/published.rb +13 -0
- data/lib/wamp/manager/event/register.rb +30 -0
- data/lib/wamp/manager/event/registered.rb +37 -0
- data/lib/wamp/manager/event/result.rb +13 -0
- data/lib/wamp/manager/event/subscribe.rb +39 -0
- data/lib/wamp/manager/event/subscribed.rb +26 -0
- data/lib/wamp/manager/event/unregister.rb +19 -0
- data/lib/wamp/manager/event/unregistered.rb +13 -0
- data/lib/wamp/manager/event/unsubscribe.rb +29 -0
- data/lib/wamp/manager/event/unsubscribed.rb +13 -0
- data/lib/wamp/manager/event/welcome.rb +21 -0
- data/lib/wamp/manager/event/yield.rb +13 -0
- data/lib/wamp/manager/event.rb +60 -0
- data/lib/wamp/manager/hello_event.rb +263 -0
- data/lib/wamp/manager/session.rb +91 -0
- data/lib/wamp/manager/subscription.rb +38 -0
- data/lib/wamp/manager.rb +12 -0
- data/lib/wamp/message_handler/api.rb +67 -0
- data/lib/wamp/message_handler/base.rb +65 -0
- data/lib/wamp/message_handler/call.rb +14 -0
- data/lib/wamp/message_handler/challenge.rb +12 -0
- data/lib/wamp/message_handler/error.rb +18 -0
- data/lib/wamp/message_handler/event.rb +18 -0
- data/lib/wamp/message_handler/goodbye.rb +19 -0
- data/lib/wamp/message_handler/hello.rb +18 -0
- data/lib/wamp/message_handler/invocation.rb +35 -0
- data/lib/wamp/message_handler/publish.rb +14 -0
- data/lib/wamp/message_handler/published.rb +18 -0
- data/lib/wamp/message_handler/register.rb +14 -0
- data/lib/wamp/message_handler/registered.rb +30 -0
- data/lib/wamp/message_handler/result.rb +17 -0
- data/lib/wamp/message_handler/subscribe.rb +14 -0
- data/lib/wamp/message_handler/subscribed.rb +30 -0
- data/lib/wamp/message_handler/unregister.rb +14 -0
- data/lib/wamp/message_handler/unregistered.rb +32 -0
- data/lib/wamp/message_handler/unsubscribe.rb +14 -0
- data/lib/wamp/message_handler/unsubscribed.rb +33 -0
- data/lib/wamp/message_handler/welcome.rb +12 -0
- data/lib/wamp/message_handler.rb +75 -0
- data/lib/wamp/router/base.rb +45 -0
- data/lib/wamp/router/client.rb +55 -0
- data/lib/wamp/router/connection.rb +150 -0
- data/lib/wamp/router/realm.rb +92 -0
- data/lib/wamp/router/server.rb +83 -0
- data/lib/wamp/router.rb +12 -0
- data/lib/wamp/serializer/cbor.rb +18 -0
- data/lib/wamp/serializer/json.rb +18 -0
- data/lib/wamp/serializer/message_pack.rb +18 -0
- data/lib/wamp/serializer.rb +5 -0
- data/lib/wamp/type/error.rb +24 -0
- data/lib/wamp/type/event.rb +16 -0
- data/lib/wamp/type/invocation.rb +16 -0
- data/lib/wamp/type/publication.rb +14 -0
- data/lib/wamp/type/registration.rb +14 -0
- data/lib/wamp/type/result.rb +16 -0
- data/lib/wamp/type/subscription.rb +14 -0
- data/lib/wamp/type/success.rb +8 -0
- data/lib/wamp/type.rb +16 -0
- data/lib/wamp/version.rb +5 -0
- data/lib/wamp.rb +15 -0
- data/mkdocs.yml +67 -0
- data/sig/wamp/serializer/json.rbs +10 -0
- data/sig/wamp.rbs +11 -0
- data/wamp.gemspec +40 -0
- metadata +223 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Published confirmation message
|
6
|
+
class Published < Base
|
7
|
+
def handle
|
8
|
+
validate_received_message
|
9
|
+
|
10
|
+
deliver_response(response)
|
11
|
+
end
|
12
|
+
|
13
|
+
def response
|
14
|
+
Type::Publication.new(publication_id: message.publication_id)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# publish event to subscriber
|
6
|
+
class Register < Base
|
7
|
+
def send_message(handler, &callback)
|
8
|
+
store[store_key] = { handler: handler, callback: callback, procedure: message.procedure }
|
9
|
+
|
10
|
+
send_serialized message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Registered callback
|
6
|
+
class Registered < Base
|
7
|
+
def handle
|
8
|
+
validate_received_message
|
9
|
+
|
10
|
+
store[alt_store_key] = { handler: stored_data.fetch(:handler), procedure: stored_data.fetch(:procedure) }
|
11
|
+
store_procedure
|
12
|
+
|
13
|
+
deliver_response(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
Type::Registration.new(registration_id: message.registration_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def alt_store_key
|
21
|
+
"registration_#{message.registration_id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def store_procedure
|
25
|
+
procedure = stored_data.fetch(:procedure)
|
26
|
+
store[procedure] = message.registration_id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Result
|
6
|
+
class Result < Base
|
7
|
+
def handle
|
8
|
+
validate_received_message
|
9
|
+
stored_data.fetch(:handler).call(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
def response
|
13
|
+
Type::Result.new(args: message.args, kwargs: message.kwargs, details: message.details)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Request subscription
|
6
|
+
class Subscribe < Base
|
7
|
+
def send_message(handler, &callback)
|
8
|
+
store[store_key] = { handler: handler, callback: callback, topic: message.topic }
|
9
|
+
|
10
|
+
send_serialized message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Receive subscribed
|
6
|
+
class Subscribed < Base
|
7
|
+
def handle
|
8
|
+
validate_received_message
|
9
|
+
|
10
|
+
store[alt_store_key] = { handler: stored_data.fetch(:handler), topic: stored_data.fetch(:topic) }
|
11
|
+
store_topic
|
12
|
+
|
13
|
+
deliver_response(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
Type::Subscription.new(subscription_id: message.subscription_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def alt_store_key
|
21
|
+
"subscription_#{message.subscription_id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def store_topic
|
25
|
+
topic = stored_data.fetch(:topic)
|
26
|
+
store[topic] = message.subscription_id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# send unregister message
|
6
|
+
class Unregister < Base
|
7
|
+
def send_message(&callback)
|
8
|
+
store[store_key] = { callback: callback, registration_id: message.registration_id }
|
9
|
+
|
10
|
+
send_serialized message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# callback for unregister message
|
6
|
+
class Unregistered < Base
|
7
|
+
def handle
|
8
|
+
validate_received_message
|
9
|
+
|
10
|
+
delete_procedure store.delete(alt_store_key)
|
11
|
+
|
12
|
+
deliver_response(response)
|
13
|
+
end
|
14
|
+
|
15
|
+
def response
|
16
|
+
Type::Success.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def alt_store_key
|
20
|
+
"registration_#{registration_id}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete_procedure(data)
|
24
|
+
store.delete data.fetch(:procedure)
|
25
|
+
end
|
26
|
+
|
27
|
+
def registration_id
|
28
|
+
stored_data.fetch(:registration_id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Request subscription
|
6
|
+
class Unsubscribe < Base
|
7
|
+
def send_message(&callback)
|
8
|
+
store[store_key] = { callback: callback, subscription_id: message.subscription_id }
|
9
|
+
|
10
|
+
send_serialized message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module MessageHandler
|
5
|
+
# Receive unsubscribed
|
6
|
+
class Unsubscribed < Base
|
7
|
+
def handle
|
8
|
+
validate_received_message
|
9
|
+
delete_topic store.delete(alt_store_key)
|
10
|
+
|
11
|
+
deliver_response(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def response
|
15
|
+
Type::Success.new
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def alt_store_key
|
21
|
+
"subscription_#{subscription_id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_topic(data)
|
25
|
+
store.delete data.fetch(:topic)
|
26
|
+
end
|
27
|
+
|
28
|
+
def subscription_id
|
29
|
+
stored_data.fetch(:subscription_id)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "message_handler/base"
|
4
|
+
|
5
|
+
require_relative "message_handler/hello"
|
6
|
+
require_relative "message_handler/welcome"
|
7
|
+
require_relative "message_handler/challenge"
|
8
|
+
require_relative "message_handler/goodbye"
|
9
|
+
|
10
|
+
require_relative "message_handler/subscribe"
|
11
|
+
require_relative "message_handler/subscribed"
|
12
|
+
require_relative "message_handler/unsubscribe"
|
13
|
+
require_relative "message_handler/unsubscribed"
|
14
|
+
|
15
|
+
require_relative "message_handler/publish"
|
16
|
+
require_relative "message_handler/published"
|
17
|
+
require_relative "message_handler/event"
|
18
|
+
|
19
|
+
require_relative "message_handler/call"
|
20
|
+
require_relative "message_handler/result"
|
21
|
+
|
22
|
+
require_relative "message_handler/register"
|
23
|
+
require_relative "message_handler/registered"
|
24
|
+
require_relative "message_handler/unregister"
|
25
|
+
require_relative "message_handler/unregistered"
|
26
|
+
|
27
|
+
require_relative "message_handler/invocation"
|
28
|
+
|
29
|
+
require_relative "message_handler/error"
|
30
|
+
|
31
|
+
require_relative "message_handler/api"
|
32
|
+
|
33
|
+
module Wamp
|
34
|
+
# routes messages
|
35
|
+
module MessageHandler
|
36
|
+
# instantiate correct handler
|
37
|
+
module ClassMethods
|
38
|
+
def resolve(data, connection)
|
39
|
+
# return handle_when_not_joined(data, connection) unless connection.joiner.joined?
|
40
|
+
|
41
|
+
message = connection.joiner.serializer.deserialize(data)
|
42
|
+
klass_name = demodulize(message.class.name)
|
43
|
+
klass = constantize("Wamp::MessageHandler::#{klass_name}")
|
44
|
+
klass.new(message, connection)
|
45
|
+
end
|
46
|
+
|
47
|
+
def handle_when_not_joined(data, connection)
|
48
|
+
authenticate = connection.joiner.receive(data) # maybe welcome message then state should be joined
|
49
|
+
connection.transmit authenticate unless connection.joiner.joined?
|
50
|
+
connection.executor.call(connection.api) if connection.joiner.joined?
|
51
|
+
Struct.new(:handle).new
|
52
|
+
end
|
53
|
+
|
54
|
+
def from(message, connection)
|
55
|
+
klass_name = demodulize(message.class.name)
|
56
|
+
klass = constantize("Wamp::MessageHandler::#{klass_name}")
|
57
|
+
klass.new(message, connection)
|
58
|
+
end
|
59
|
+
|
60
|
+
def demodulize(path)
|
61
|
+
path = path.to_s
|
62
|
+
if i = path.rindex("::") # rubocop:disable Lint/AssignmentInCondition
|
63
|
+
path[(i + 2), path.length]
|
64
|
+
else
|
65
|
+
path
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def constantize(camel_cased_word)
|
70
|
+
Object.const_get(camel_cased_word)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
extend ClassMethods
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "realm"
|
4
|
+
|
5
|
+
module Wamp
|
6
|
+
module Router
|
7
|
+
# Router
|
8
|
+
class Base
|
9
|
+
attr_reader :realms
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@realms = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_realm(name)
|
16
|
+
realms[name] = Realm.new(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_realm(name)
|
20
|
+
realms.delete(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def attach_client(client)
|
24
|
+
error_message = "cannot attach client to non-existent realm #{client.realm}"
|
25
|
+
raise Wampproto::ValueError, error_message unless realms.include?(client.realm)
|
26
|
+
|
27
|
+
realms[client.realm].attach_client(client)
|
28
|
+
end
|
29
|
+
|
30
|
+
def detach_client(client)
|
31
|
+
error_message = "cannot attach client to non-existent realm #{client.realm}"
|
32
|
+
raise Wampproto::ValueError, error_message unless realms.include?(client.realm)
|
33
|
+
|
34
|
+
realms[client.realm].detach_client(client)
|
35
|
+
end
|
36
|
+
|
37
|
+
def receive_message(client, message)
|
38
|
+
error_message = "cannot attach client to non-existent realm #{client.realm}"
|
39
|
+
raise Wampproto::ValueError, error_message unless realms.include?(client.realm)
|
40
|
+
|
41
|
+
realms[client.realm].receive_message(client.session_id, message)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "realm"
|
4
|
+
|
5
|
+
module Wamp
|
6
|
+
module Router
|
7
|
+
# Auth
|
8
|
+
class Authenticator
|
9
|
+
def self.authenticate(request)
|
10
|
+
Wampproto::Acceptor::Response.new(request.authid, "role", "secret")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Server Session
|
15
|
+
class Client
|
16
|
+
attr_accessor :router, :connection
|
17
|
+
attr_reader :acceptor, :serializer
|
18
|
+
|
19
|
+
def initialize(serializer = Wampproto::Serializer::JSON, authenticator = Authenticator)
|
20
|
+
@serializer = serializer
|
21
|
+
@acceptor = Wampproto::Acceptor.new(serializer, authenticator)
|
22
|
+
end
|
23
|
+
|
24
|
+
def realm
|
25
|
+
acceptor.session_details&.realm
|
26
|
+
end
|
27
|
+
|
28
|
+
def send_message(message)
|
29
|
+
transmit(message)
|
30
|
+
end
|
31
|
+
|
32
|
+
def session_id
|
33
|
+
acceptor.session_details&.session_id
|
34
|
+
end
|
35
|
+
|
36
|
+
def transmit(data)
|
37
|
+
case data
|
38
|
+
when Wampproto::Message::Base
|
39
|
+
connection.on_message serializer.serialize(data)
|
40
|
+
else
|
41
|
+
connection.on_message data
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_message(data)
|
46
|
+
unless acceptor.accepted?
|
47
|
+
msg, is_welcome = acceptor.receive(data)
|
48
|
+
transmit msg
|
49
|
+
router.attach_client(self) if is_welcome
|
50
|
+
end
|
51
|
+
router.receive_message(self, serializer.deserialize(data))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "websocket/driver"
|
4
|
+
|
5
|
+
# Testing
|
6
|
+
class Authenticator
|
7
|
+
def self.authenticate(request)
|
8
|
+
Wampproto::Acceptor::Response.new(request.authid, "role")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Wamp
|
13
|
+
module Router
|
14
|
+
# TOP Level Doc
|
15
|
+
class Connection < Client # rubocop:disable Metrics/ClassLength
|
16
|
+
include WebSocket::Driver::EventEmitter
|
17
|
+
CONNECTING = 0
|
18
|
+
OPEN = 1
|
19
|
+
CLOSING = 2
|
20
|
+
CLOSED = 3
|
21
|
+
|
22
|
+
attr_reader :socket, :session, :acceptor
|
23
|
+
|
24
|
+
def initialize(socket, &cleanup)
|
25
|
+
super()
|
26
|
+
@cleanup = cleanup
|
27
|
+
@socket = socket
|
28
|
+
@driver = WebSocket::Driver.server(self)
|
29
|
+
@driver.on(:open) { on_open(_1) }
|
30
|
+
@driver.on(:message) { on_message(_1.data) }
|
31
|
+
@driver.on(:close) { |evt| begin_close(evt.reason, evt.code) }
|
32
|
+
@driver.on(:connect) { on_connect }
|
33
|
+
@ready_state = CONNECTING
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_connect
|
37
|
+
@driver.start if WebSocket::Driver.websocket?(@driver.env)
|
38
|
+
choose_serializer_from @driver.env["HTTP_SEC_WEBSOCKET_PROTOCOL"]
|
39
|
+
@acceptor = Wampproto::Acceptor.new(serializer, Authenticator)
|
40
|
+
end
|
41
|
+
|
42
|
+
def connection
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def begin_close(reason, code)
|
47
|
+
return if @ready_state == CLOSED
|
48
|
+
|
49
|
+
@ready_state = CLOSING
|
50
|
+
@close_params = [reason, code]
|
51
|
+
|
52
|
+
@cleanup&.call(self)
|
53
|
+
finalize_close
|
54
|
+
end
|
55
|
+
|
56
|
+
def finalize_close
|
57
|
+
return if @ready_state == CLOSED
|
58
|
+
|
59
|
+
@ready_state = CLOSED
|
60
|
+
@driver.close
|
61
|
+
socket.close
|
62
|
+
end
|
63
|
+
|
64
|
+
def listen(&block) # rubocop:disable Metrics/MethodLength
|
65
|
+
return unless [CONNECTING, OPEN].include?(@ready_state)
|
66
|
+
|
67
|
+
begin
|
68
|
+
data = socket.read_nonblock(4096, exception: false)
|
69
|
+
case data
|
70
|
+
when :wait_readable
|
71
|
+
# do nothing
|
72
|
+
when nil
|
73
|
+
block&.call
|
74
|
+
@driver.close
|
75
|
+
else
|
76
|
+
receive_data(data)
|
77
|
+
end
|
78
|
+
rescue StandardError => e
|
79
|
+
puts e.message
|
80
|
+
puts e.backtrace
|
81
|
+
begin
|
82
|
+
block&.call
|
83
|
+
@driver.close
|
84
|
+
rescue StandardError
|
85
|
+
# Errno::ECONNRESET
|
86
|
+
puts "Failed to handle: Errno::ECONNRESET"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# triggers on_message
|
92
|
+
def receive_data(data)
|
93
|
+
return unless [OPEN, CONNECTING].include?(@ready_state)
|
94
|
+
|
95
|
+
@driver.parse(data)
|
96
|
+
end
|
97
|
+
|
98
|
+
# called when @driver.text is invoked
|
99
|
+
def write(data)
|
100
|
+
socket.write(data)
|
101
|
+
end
|
102
|
+
|
103
|
+
def transmit(message)
|
104
|
+
# return false if @ready_state > OPEN
|
105
|
+
|
106
|
+
case message
|
107
|
+
when Wampproto::Message::Base then transmit(serializer.serialize(message))
|
108
|
+
when Numeric then @driver.text(message.to_s)
|
109
|
+
when String then @driver.text(message)
|
110
|
+
when Array then @driver.binary(message)
|
111
|
+
else false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def on_open(_evt)
|
118
|
+
return unless @ready_state == CONNECTING
|
119
|
+
|
120
|
+
@ready_state = OPEN
|
121
|
+
end
|
122
|
+
|
123
|
+
def on_close(message)
|
124
|
+
return if @ready_state == CLOSED
|
125
|
+
|
126
|
+
@ready_state = CLOSED
|
127
|
+
socket.close
|
128
|
+
@driver.close(message.code, message.reason)
|
129
|
+
end
|
130
|
+
|
131
|
+
def close(_code, _reason)
|
132
|
+
@driver.close
|
133
|
+
end
|
134
|
+
|
135
|
+
attr_reader :serializer
|
136
|
+
|
137
|
+
def choose_serializer_from(protocols)
|
138
|
+
@serializer = if protocols.include?("wamp.2.msgpack")
|
139
|
+
Wampproto::Serializer::Msgpack
|
140
|
+
elsif protocols.include?("wamp.2.cbor")
|
141
|
+
Wampproto::Serializer::Cbor
|
142
|
+
elsif protocols.include?("wamp.2.json")
|
143
|
+
Wampproto::Serializer::JSON
|
144
|
+
else
|
145
|
+
close
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wamp
|
4
|
+
module Router
|
5
|
+
# Realm
|
6
|
+
class Realm
|
7
|
+
attr_reader :broker, :dealer, :name, :clients
|
8
|
+
|
9
|
+
DEALER_MESSAGES = [
|
10
|
+
Wampproto::Message::Call,
|
11
|
+
Wampproto::Message::Yield,
|
12
|
+
Wampproto::Message::Register,
|
13
|
+
Wampproto::Message::Unregister
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
BROKER_MESSAGES = [
|
17
|
+
Wampproto::Message::Publish,
|
18
|
+
Wampproto::Message::Subscribe,
|
19
|
+
Wampproto::Message::Unsubscribe
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
GOODBYE_MESSAGE = Wampproto::Message::Goodbye
|
23
|
+
|
24
|
+
def initialize(name)
|
25
|
+
@name = name
|
26
|
+
@broker = Wampproto::Broker.new(id_gen)
|
27
|
+
@dealer = Wampproto::Dealer.new(id_gen)
|
28
|
+
@clients = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def attach_client(client)
|
32
|
+
session_id = client.session_id
|
33
|
+
session_details = client.acceptor.session_details
|
34
|
+
|
35
|
+
clients[session_id] = client
|
36
|
+
broker.add_session(session_details)
|
37
|
+
dealer.add_session(session_details)
|
38
|
+
end
|
39
|
+
|
40
|
+
def detach_client(client)
|
41
|
+
remove_client(client.session_id)
|
42
|
+
end
|
43
|
+
|
44
|
+
def clear
|
45
|
+
clients.each { |client| remove_client(client.session_id) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def receive_message(session_id, message)
|
49
|
+
case message
|
50
|
+
when *DEALER_MESSAGES then handle_dealer(session_id, message)
|
51
|
+
when *BROKER_MESSAGES then handle_broker(session_id, message)
|
52
|
+
when GOODBYE_MESSAGE then handle_goodbye(session_id, message)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def handle_dealer(session_id, message)
|
59
|
+
send_message dealer.receive_message(session_id, message)
|
60
|
+
end
|
61
|
+
|
62
|
+
def handle_broker(session_id, message)
|
63
|
+
send_message broker.receive_message(session_id, message)
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle_goodbye(session_id, _message)
|
67
|
+
goodbye = Wampproto::Message::Goodbye.new({}, "wamp.close.goodbye_and_out")
|
68
|
+
send_message Wampproto::MessageWithRecipient.new(goodbye, session_id)
|
69
|
+
end
|
70
|
+
|
71
|
+
def send_message(message_with_receipient)
|
72
|
+
Array(message_with_receipient).each do |object|
|
73
|
+
client = clients[object.recipient]
|
74
|
+
|
75
|
+
next unless client
|
76
|
+
|
77
|
+
client.send_message object.message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def id_gen
|
82
|
+
@id_gen ||= Wampproto::IdGenerator.new
|
83
|
+
end
|
84
|
+
|
85
|
+
def remove_client(session_id)
|
86
|
+
broker.remove_session(session_id)
|
87
|
+
dealer.remove_session(session_id)
|
88
|
+
clients.delete(session_id)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|