1 2 3 4 5 6 7 8 9 10 11 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
|
#!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH << File.expand_path("../../lib", __dir__)
require 'async'
require 'async/notification'
require 'async/io/stream'
require 'async/io/host_endpoint'
require 'async/io/protocol/line'
class User < Async::IO::Protocol::Line
end
endpoint = Async::IO::Endpoint.parse(ARGV.pop || "tcp://localhost:7138")
input = Async::IO::Protocol::Line.new(
Async::IO::Stream.new(
Async::IO::Generic.new($stdin)
)
)
Async do |task|
socket = endpoint.connect
stream = Async::IO::Stream.new(socket)
user = User.new(stream)
# This is used to track whether either reading from stdin failed or reading from network failed.
finished = Async::Notification.new
# Read lines from stdin and write to network.
terminal = task.async do
while line = input.read_line
user.write_lines line
end
rescue EOFError
# It's okay, we are disconnecting, because stdin has closed.
ensure
finished.signal
end
# Read lines from network and write to stdout.
network = task.async do
while line = user.read_line
puts line
end
ensure
finished.signal
end
# Wait for any of the above processes to finish:
finished.wait
ensure
# Stop all the nested tasks if we are exiting:
network.stop if network
terminal.stop if terminal
user.close if user
end
|