Class: Rancher::Shell::WebsocketClient

Inherits:
Object
  • Object
show all
Includes:
EventEmitter, LoggerHelper
Defined in:
lib/rancher/shell/websocket_client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from LoggerHelper

#exit_with_error, #logger

Constructor Details

#initialize(url, options = {}) ⇒ WebsocketClient

Returns a new instance of WebsocketClient.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
# File 'lib/rancher/shell/websocket_client.rb', line 12

def initialize 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] || 'SSLv23'
    ctx.verify_mode = options[:verify_mode] || OpenSSL::SSL::VERIFY_NONE #use VERIFY_PEER for verification
    cert_store = OpenSSL::X509::Store.new
    cert_store.set_default_paths
    ctx.cert_store = cert_store
    @socket = ::OpenSSL::SSL::SSLSocket.new(@socket, ctx)
    @socket.connect
  end
  @handshake = ::WebSocket::Handshake::Client.new :url => url, :headers => options[:headers]
  @handshaked = false
  @pipe_broken = false
  frame = ::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 :chunk, msg.to_s
          end
        end
      rescue => e
        puts "EMIT ERROR: #{e.to_yaml}"
        emit :error, e
      end
    end
    puts "THREAD IS DEAD"
  end

  @socket.write @handshake.to_s
end

Instance Attribute Details

#handshakeObject (readonly)

Returns the value of attribute handshake.



10
11
12
# File 'lib/rancher/shell/websocket_client.rb', line 10

def handshake
  @handshake
end

#handshakedObject (readonly)

Returns the value of attribute handshaked.



10
11
12
# File 'lib/rancher/shell/websocket_client.rb', line 10

def handshaked
  @handshaked
end

#socketObject (readonly)

Returns the value of attribute socket.



10
11
12
# File 'lib/rancher/shell/websocket_client.rb', line 10

def socket
  @socket
end

#threadObject (readonly)

Returns the value of attribute thread.



10
11
12
# File 'lib/rancher/shell/websocket_client.rb', line 10

def thread
  @thread
end

#urlObject (readonly)

Returns the value of attribute url.



10
11
12
# File 'lib/rancher/shell/websocket_client.rb', line 10

def url
  @url
end

Instance Method Details

#closeObject



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rancher/shell/websocket_client.rb', line 82

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

#open?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/rancher/shell/websocket_client.rb', line 94

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

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



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rancher/shell/websocket_client.rb', line 67

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