Skip to content

Commit b1860a4

Browse files
authored
Ensure the client is closed when closing the connection. (#47)
1 parent 9761ff4 commit b1860a4

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

lib/async/websocket/client.rb

+21-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
require 'async/http/client'
1414

15+
require 'delegate'
16+
1517
module Async
1618
module WebSocket
1719
# This is a basic synchronous websocket client:
@@ -31,13 +33,29 @@ def self.open(endpoint, **options, &block)
3133
end
3234
end
3335

36+
class ClientCloseDecorator < SimpleDelegator
37+
def initialize(client, connection)
38+
@client = client
39+
super(connection)
40+
end
41+
42+
def close
43+
super
44+
45+
if @client
46+
@client.close
47+
@client = nil
48+
end
49+
end
50+
end
51+
3452
# @return [Connection] an open websocket connection to the given endpoint.
3553
def self.connect(endpoint, *arguments, **options, &block)
3654
client = self.open(endpoint, *arguments)
3755
connection = client.connect(endpoint.authority, endpoint.path, **options)
38-
39-
return connection unless block_given?
40-
56+
57+
return ClientCloseDecorator.new(client, connection) unless block_given?
58+
4159
begin
4260
yield connection
4361
ensure

test/async/websocket/client.rb

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
3+
ClientExamples = Sus::Shared("a websocket client") do
4+
include Sus::Fixtures::Async::HTTP::ServerContext
5+
6+
let(:app) do
7+
Protocol::HTTP::Middleware.for do |request|
8+
Async::WebSocket::Adapters::HTTP.open(request) do |connection|
9+
while message = connection.read
10+
connection.write(message)
11+
end
12+
13+
connection.close
14+
end or Protocol::HTTP::Response[404, {}, []]
15+
end
16+
end
17+
18+
let(:timeout) {nil}
19+
20+
it "can connect to a websocket server and close underlying client" do
21+
connection = Async::WebSocket::Client.connect(client_endpoint)
22+
connection.send_text("Hello World!")
23+
message = connection.read
24+
expect(message.to_str).to be == "Hello World!"
25+
connection.close
26+
end
27+
end
28+
29+
describe Async::WebSocket::Client do
30+
with "h1", protocol: Async::HTTP::Protocol::HTTP1 do
31+
it_behaves_like ClientExamples
32+
end
33+
34+
with "h2", protocol: Async::HTTP::Protocol::HTTP2 do
35+
it_behaves_like ClientExamples
36+
end
37+
end

test/async/websocket/server.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
require 'sus/fixtures/async/http/server_context'
1313

14-
WebSocketServerExamples = Sus::Shared('a websocket server') do
14+
ServerExamples = Sus::Shared('a websocket server') do
1515
include Sus::Fixtures::Async::HTTP::ServerContext
1616

1717
let(:message) {"Hello World"}
@@ -72,11 +72,11 @@
7272
describe Async::HTTP::Protocol::HTTP1 do
7373
let(:protocol) {subject}
7474

75-
it_behaves_like WebSocketServerExamples
75+
it_behaves_like ServerExamples
7676
end
7777

7878
describe Async::HTTP::Protocol::HTTP2 do
7979
let(:protocol) {subject}
8080

81-
it_behaves_like WebSocketServerExamples
81+
it_behaves_like ServerExamples
8282
end

0 commit comments

Comments
 (0)