Class: Async::WebSocket::Client

Inherits:
Protocol::HTTP::Middleware
  • Object
show all
Includes:
Protocol::WebSocket::Headers
Defined in:
lib/async/websocket/client.rb

Overview

This is a basic synchronous websocket client:

Defined Under Namespace

Classes: Framer

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, **options) ⇒ Client



49
50
51
52
53
# File 'lib/async/websocket/client.rb', line 49

def initialize(client, **options)
  super(client)
  
  @options = options
end

Class Method Details

.connect(endpoint, *arguments, **options, &block) ⇒ Connection



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/async/websocket/client.rb', line 35

def self.connect(endpoint, *arguments, **options, &block)
  client = self.open(endpoint, *arguments)
  connection = client.connect(endpoint.authority, endpoint.path, **options)
    
  return connection unless block_given?
    
  begin
    yield connection
  ensure
    connection.close
    client.close
  end
end

.open(endpoint, **options, &block) ⇒ Client



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/async/websocket/client.rb', line 22

def self.open(endpoint, **options, &block)
  client = self.new(HTTP::Client.new(endpoint, **options), mask: true)
  
  return client unless block_given?
  
  begin
    yield client
  ensure
    client.close
  end
end

Instance Method Details

#connect(authority, path, headers: nil, handler: Connection, extensions: ::Protocol::WebSocket::Extensions::Client.default, **options, &block) ⇒ Object



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
# File 'lib/async/websocket/client.rb', line 73

def connect(authority, path, headers: nil, handler: Connection, extensions: ::Protocol::WebSocket::Extensions::Client.default, **options, &block)
  headers = ::Protocol::HTTP::Headers[headers]
  
  extensions&.offer do |extension|
    headers.add(SEC_WEBSOCKET_EXTENSIONS, extension.join("; "))
  end
  
  request = Request.new(nil, authority, path, headers, **options)
  
  pool = @delegate.pool
  connection = pool.acquire
  
  response = request.call(connection)
  
  unless response.stream?
    raise ProtocolError, "Failed to negotiate connection: #{response.status}"
  end
  
  protocol = response.headers[SEC_WEBSOCKET_PROTOCOL]&.first
  stream = response.stream
  
  framer = Framer.new(pool, connection, stream)
  
  connection = nil
  
  if extension_headers = response.headers[SEC_WEBSOCKET_EXTENSIONS]
    extensions.accept(extension_headers)
  end
  
  response = nil
  stream = nil
  
  connction = handler.call(framer, protocol, extensions, **@options, &block)
ensure
  pool.release(connection) if connection
end