Class: Peatio::Ranger::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/peatio/ranger/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(router, socket, logger) ⇒ Connection

Returns a new instance of Connection.



5
6
7
8
9
10
11
12
13
# File 'lib/peatio/ranger/connection.rb', line 5

def initialize(router, socket, logger)
  @id = SecureRandom.hex(10)
  @router = router
  @socket = socket
  @logger = logger
  @user = nil
  @authorized = false
  @streams = {}
end

Instance Attribute Details

#authorizedObject (readonly)

Returns the value of attribute authorized.



3
4
5
# File 'lib/peatio/ranger/connection.rb', line 3

def authorized
  @authorized
end

#idObject (readonly)

Returns the value of attribute id.



3
4
5
# File 'lib/peatio/ranger/connection.rb', line 3

def id
  @id
end

#loggerObject (readonly)

Returns the value of attribute logger.



3
4
5
# File 'lib/peatio/ranger/connection.rb', line 3

def logger
  @logger
end

#socketObject (readonly)

Returns the value of attribute socket.



3
4
5
# File 'lib/peatio/ranger/connection.rb', line 3

def socket
  @socket
end

#streamsObject (readonly)

Returns the value of attribute streams.



3
4
5
# File 'lib/peatio/ranger/connection.rb', line 3

def streams
  @streams
end

#userObject (readonly)

Returns the value of attribute user.



3
4
5
# File 'lib/peatio/ranger/connection.rb', line 3

def user
  @user
end

Instance Method Details

#authenticate(authenticator, jwt) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/peatio/ranger/connection.rb', line 37

def authenticate(authenticator, jwt)
  payload = {}
  authorized = false
  begin
    payload = authenticator.authenticate!(jwt)
    authorized = true
  rescue Peatio::Auth::Error => e
    logger.warn e.message
  end
  [authorized, payload]
end

#handle(msg) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/peatio/ranger/connection.rb', line 79

def handle(msg)
  return if msg.to_s.empty?

  if msg =~ /^ping/
    send_raw("pong")
    return
  end

  data = JSON.parse(msg)
  case data["event"]
  when "subscribe"
    subscribe(data["streams"])
  when "unsubscribe"
    unsubscribe(data["streams"])
  end
rescue JSON::ParserError => e
  logger.debug { "#{e}, msg: `#{msg}`" }
end

#handshake(authenticator, hs) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/peatio/ranger/connection.rb', line 98

def handshake(authenticator, hs)
  query = URI.decode_www_form(hs.query_string)
  subscribe(query.map {|item| item.last if item.first == "stream" })
  logger.debug "WebSocket connection openned"
  headers = hs.headers_downcased
  return unless headers.key?("authorization")

  authorized, payload = authenticate(authenticator, headers["authorization"])

  if !authorized
    logger.debug "Authentication failed for UID:#{payload[:uid]}"
    raise EM::WebSocket::HandshakeError, "Authorization failed"
  else
    @user = payload[:uid]
    @authorized = true
    logger.debug "User #{@user} authenticated #{@streams}"
  end
end

#inspectObject



15
16
17
18
19
20
21
# File 'lib/peatio/ranger/connection.rb', line 15

def inspect
  if authorized
    "<Connection id=#{id} user=#{user}>"
  else
    "<Connection id=#{id}>"
  end
end

#send(method, data) ⇒ Object



32
33
34
35
# File 'lib/peatio/ranger/connection.rb', line 32

def send(method, data)
  payload = JSON.dump(method => data)
  send_raw(payload)
end

#send_raw(payload) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/peatio/ranger/connection.rb', line 23

def send_raw(payload)
  if user
    logger.debug { "sending to user #{user.inspect} payload: #{payload}" }
  else
    logger.debug { "sending to anonymous payload: #{payload}" }
  end
  @socket.send(payload)
end

#subscribe(subscribed_streams) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/peatio/ranger/connection.rb', line 49

def subscribe(subscribed_streams)
  raise "Streams must be an array of strings" unless subscribed_streams.is_a?(Array)

  subscribed_streams.each do |stream|
    stream = stream.to_s
    next if stream.empty?

    unless @streams[stream]
      @streams[stream] = true
      @router.on_subscribe(self, stream)
    end
  end
  send(:success, message: "subscribed", streams: streams.keys)
end

#unsubscribe(unsubscribed_streams) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/peatio/ranger/connection.rb', line 64

def unsubscribe(unsubscribed_streams)
  raise "Streams must be an array of strings" unless unsubscribed_streams.is_a?(Array)

  unsubscribed_streams.each do |stream|
    stream = stream.to_s
    next if stream.empty?

    if @streams[stream]
      @streams.delete(stream)
      @router.on_unsubscribe(self, stream)
    end
  end
  send(:success, message: "unsubscribed", streams: streams.keys)
end