Class: NewRelic::Security::WebSocket::Client::Simple::Client

Inherits:
Object
  • Object
show all
Includes:
EventEmitter
Defined in:
lib/newrelic_security/websocket-client-simple/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from EventEmitter

apply, included

Constructor Details

#initializeClient

Returns a new instance of Client.



23
24
25
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 23

def initialize
  @socket = nil
end

Instance Attribute Details

#handshakeObject (readonly)

Returns the value of attribute handshake.



21
22
23
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 21

def handshake
  @handshake
end

#urlObject (readonly)

Returns the value of attribute url.



21
22
23
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 21

def url
  @url
end

Instance Method Details

#close(reconnect = true) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 107

def close(reconnect = true)
  return if @closed
  if !@pipe_broken
    send nil, :type => :close
  end
  @closed = true
  @socket.close if @socket
  @socket = nil
  emit :__close, reconnect
  Thread.kill @thread if @thread
end

#closed?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 123

def closed?
  @closed
end

#connect(url, options = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 27

def connect(url, options={})
  return if @socket
  @url = url
  uri = URI.parse url
  @socket = TCPSocket.new(uri.host,
                          uri.port || (uri.scheme == 'wss' ? 443 : 80))
  if ['https', 'wss'].include? uri.scheme
    ctx = OpenSSL::SSL::SSLContext.new
    ctx.ssl_version = options[:ssl_version] if options[:ssl_version]
    ctx.verify_mode = options[:verify_mode] if options[:verify_mode]
    cert_store = options[:cert_store] || OpenSSL::X509::Store.new
    cert_store.set_default_paths
    ctx.cert_store = cert_store
    @socket = ::OpenSSL::SSL::SSLSocket.new(@socket, ctx)
    @socket.sync_close = true
    @socket.hostname = uri.host
    @socket.connect
  end
  @handshake = NewRelic::Security::WebSocket::Handshake::Client.new :url => url, :headers => options[:headers]
  @handshaked = false
  @pipe_broken = false
  frame = NewRelic::Security::WebSocket::Frame::Incoming::Client.new
  @closed = false
  once :__close do |err|
    close
    emit :close, err
  end
  
  @thread = Thread.new do
    while !@closed do
      begin
        unless recv_data = @socket.getc
          sleep 1
          next
        end
        unless @handshaked
          @handshake << recv_data
          if @handshake.finished?
            @handshaked = true
            emit :open
          end
        else
          frame << recv_data
          while msg = frame.next
            emit :message, msg
          end
        end
      rescue IOError => e
        if e.inspect =~ /stream closed in another thread/
          close false
        else
          emit :error, e
        end
      rescue => e
        emit :error, e
      end
    end
  end
  
  @socket.write @handshake.to_s
end

#open?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 119

def open?
  @handshake&.finished? and !@closed
end

#send(data, opt = {:type => :text}) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/newrelic_security/websocket-client-simple/client.rb', line 89

def send(data, opt={:type => :text})
  return if !@handshaked or @closed
  type = opt[:type]
  frame = NewRelic::Security::WebSocket::Frame::Outgoing::Client.new(:data => data, :type => type, :version => @handshake.version)
  begin
    @socket.write frame.to_s
  rescue IOError => e
    @pipe_broken = true
    emit :__close, e
  rescue Errno::EPIPE => e
    @pipe_broken = true
    emit :__close, e
  rescue OpenSSL::SSL::SSLError => e
    @pipe_broken = true
    emit :__close, e
  end
end