Module: WAMP

Defined in:
lib/wamp_server.rb,
lib/version.rb

Overview

Constant Summary collapse

VERSION =
'0.2'
WELCOME =
0
PREFIX =
1
CALL =
2
CALLRESULT =
3
CALLERROR =
4
SUBSCRIBE =
5
UNSUBSCRIBE =
6
PUBLISH =
7
EVENT =
8
RESPONSES =
{ :not_json => { :error => 'Message is not JSON !' }.to_json }

Class Method Summary collapse

Class Method Details

.stampObject



22
23
24
# File 'lib/wamp_server.rb', line 22

def self.stamp
  "#{self.name} #{VERSION}"
end

.start_server(a_module, opts = {}) ⇒ Object

Start a new Server

You should pass some callbacks:

:before_start => To be called before actually starting the server, but already within EM reactor.
:onwelcome => To be called for WELCOME calls.
:onprefix => To be called for PREFIX calls.
:oncall => To be called when server receives a CALL call.
:onpublish => To be called when server receives a PUBLISH call.
:onclose => To be called when a client closes connection.
:onsubscribe => Called for SUBSCRIBE calls.
:onunsubscribe => On UNSUBSCRIBE calls.


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/wamp_server.rb', line 44

def self.start_server(a_module, opts = {})

  # avoid more instances
  a = a_module
  a.extend a

  host = opts[:host] || '0.0.0.0'
  port = opts[:port] || '3000'

  EM.run do

    trap("INT") { WAMP.stop_server }
    trap("TERM") { WAMP.stop_server }
    trap("KILL") { WAMP.stop_server }

    a.before_start if a.respond_to?(:before_start)

    puts "Listening on #{host}:#{port}"
    WebSocket::EventMachine::Server.start(:host => host, :port => port) do |ws|

      ws.onopen do
        Fiber.new do
          sid = a.onwelcome ws: ws
          ws.send [WAMP::WELCOME, sid, 1, WAMP.stamp].to_json
        end.resume
      end

      ws.onmessage do |msg, type|
        Fiber.new do
          begin
            call = JSON.parse msg
          rescue JSON::ParserError
            ws.send( WAMP::RESPONSES[:not_json] )
          end

          if call.first == WAMP::CALL then
            # [ TYPE_ID_CALL , callID , procURI , ... ]
            _, callid, curie, *args = call
            begin
              result = a.oncall ws: ws, curie: curie, args: args
              ws.send [WAMP::CALLRESULT, callid, result].to_json
            rescue => ex
              ws.send [WAMP::CALLERROR, callid, "http://error", ex.to_s].to_json
            end
          elsif call.first == WAMP::PUBLISH then
            # [ TYPE_ID_PUBLISH , topicURI , event , exclude , eligible ]
            _, curie, event, excluded, eligible = call
            result = a.onpublish curie: curie
            dest = (result[:subscribed] & eligible) - excluded
            package = [WAMP::EVENT, result[:uri], event].to_json
            dest.each do |d|
              ObjectSpace._id2ref(d).send( package )
            end
          elsif call.first == WAMP::SUBSCRIBE then
            # [ TYPE_ID_SUBSCRIBE , topicURI ]
            a.onsubscribe ws: ws, curie: call[1]
          elsif call.first == WAMP::UNSUBSCRIBE then
            # [ TYPE_ID_UNSUBSCRIBE , topicURI ]
            a.onunsubscribe ws: ws, curie: call[1]
          elsif call.first == WAMP::PREFIX then
            # [ TYPE_ID_PREFIX , prefix, URI ]
            _, prefix, uri = call
            a.onprefix ws: ws, uri: uri, prefix: prefix
          end
        end.resume
      end

      ws.onclose do
        Fiber.new do
          a.onclose ws: ws
        end.resume
      end

    end # Server.start
  end # EM.run

end

.stop_serverObject



26
27
28
29
# File 'lib/wamp_server.rb', line 26

def self.stop_server
  puts "Terminating WebSocket Server"
  EM.stop
end