Class: Net::SSH::Multi::Channel

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/net/ssh/multi/channel.rb

Overview

Net::SSH::Multi::Channel encapsulates a collection of Net::SSH::Connection::Channel instances from multiple different connections. It allows for operations to be performed on all contained channels, simultaneously, using an interface mostly identical to Net::SSH::Connection::Channel itself.

You typically obtain a Net::SSH::Multi::Channel instance via Net::SSH::Multi::Session#open_channel or Net::SSH::Multi::Session#exec, though there is nothing stopping you from instantiating one yourself with a handful of Net::SSH::Connection::Channel objects (though they should be associated with connections managed by a Net::SSH::Multi::Session object for consistent behavior).

channel = session.open_channel do |ch|
  # ...
end

channel.wait

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, channels) ⇒ Channel

Instantiate a new Net::SSH::Multi::Channel instance, controlled by the given connection (a Net::SSH::Multi::Session object) and wrapping the given channels (Net::SSH::Connection::Channel instances).

You will typically never call this directly; rather, you’ll get your multi-channel references via Net::SSH::Multi::Session#open_channel and friends.



38
39
40
41
42
# File 'lib/net/ssh/multi/channel.rb', line 38

def initialize(connection, channels)
  @connection = connection
  @channels = channels
  @properties = {}
end

Instance Attribute Details

#channelsObject (readonly)

The collection of Net::SSH::Connection::Channel instances that this multi-channel aggregates.



26
27
28
# File 'lib/net/ssh/multi/channel.rb', line 26

def channels
  @channels
end

#connectionObject (readonly)

The Net::SSH::Multi::Session instance that controls this channel collection.



23
24
25
# File 'lib/net/ssh/multi/channel.rb', line 23

def connection
  @connection
end

#propertiesObject (readonly)

A Hash of custom properties that may be set and queried on this object.



29
30
31
# File 'lib/net/ssh/multi/channel.rb', line 29

def properties
  @properties
end

Instance Method Details

#[](key) ⇒ Object

Retrieve the property (see #properties) with the given key.

host = channel[:host]


53
54
55
# File 'lib/net/ssh/multi/channel.rb', line 53

def [](key)
  @properties[key]
end

#[]=(key, value) ⇒ Object

Set the property (see #properties) with the given key to the given value.

channel[:visited] = true


61
62
63
# File 'lib/net/ssh/multi/channel.rb', line 61

def []=(key, value)
  @properties[key] = value
end

#active?Boolean

Returns true as long as any of the component channels are active.

connection.loop { channel.active? }

Returns:

  • (Boolean)


112
113
114
# File 'lib/net/ssh/multi/channel.rb', line 112

def active?
  channels.any? { |channel| channel.active? }
end

#closeObject

Closes all component channels.



127
128
129
130
# File 'lib/net/ssh/multi/channel.rb', line 127

def close
  channels.each { |channel| channel.close }
  self
end

#eachObject

Iterate over each component channel object, yielding each in order to the associated block.



46
47
48
# File 'lib/net/ssh/multi/channel.rb', line 46

def each
  @channels.each { |channel| yield channel }
end

#eof!Object

Tells the remote process for each component channel not to expect any further data from this end of the channel.



134
135
136
137
# File 'lib/net/ssh/multi/channel.rb', line 134

def eof!
  channels.each { |channel| channel.eof! }
  self
end

#exec(command, &block) ⇒ Object

Perform an exec command on all component channels. The block, if given, is passed to each component channel, so it will (potentially) be invoked once for every channel in the collection. The block will receive two parameters: the specific channel object being operated on, and a boolean indicating whether the exec succeeded or not.

channel.exec "ls -l" do |ch, success|
  # ...
end

See the documentation in Net::SSH for Net::SSH::Connection::Channel#exec for more information on how to work with the callback.



77
78
79
80
# File 'lib/net/ssh/multi/channel.rb', line 77

def exec(command, &block)
  channels.each { |channel| channel.exec(command, &block) }
  self
end

#on_close(&block) ⇒ Object

Registers a callback on all component channels, to be invoked when the remote server terminates the channel. The callback will be invoked with one argument: the specific channel object being closed.

channel.on_close do |ch|
  # ...
end


185
186
187
188
# File 'lib/net/ssh/multi/channel.rb', line 185

def on_close(&block)
  channels.each { |channel| channel.on_close(&block) }
  self
end

#on_data(&block) ⇒ Object

Registers a callback on all component channels, to be invoked when the remote process emits data (usually on its stdout stream). The block will be invoked with two arguments: the specific channel object, and the data that was received.

channel.on_data do |ch, data|
  puts "got data: #{data}"
end


147
148
149
150
# File 'lib/net/ssh/multi/channel.rb', line 147

def on_data(&block)
  channels.each { |channel| channel.on_data(&block) }
  self
end

#on_eof(&block) ⇒ Object

Registers a callback on all component channels, to be invoked when the remote server has no further data to send. The callback will be invoked with one argument: the specific channel object being marked EOF.

channel.on_eof do |ch|
  # ...
end


197
198
199
200
# File 'lib/net/ssh/multi/channel.rb', line 197

def on_eof(&block)
  channels.each { |channel| channel.on_eof(&block) }
  self
end

#on_extended_data(&block) ⇒ Object

Registers a callback on all component channels, to be invoked when the remote process emits “extended” data (typically on its stderr stream). The block will be invoked with three arguments: the specific channel object, an integer describing the data type (usually a 1 for stderr) and the data that was received.

channel.on_extended_data do |ch, type, data|
  puts "got extended data: #{data}"
end


161
162
163
164
# File 'lib/net/ssh/multi/channel.rb', line 161

def on_extended_data(&block)
  channels.each { |channel| channel.on_extended_data(&block) }
  self
end

#on_open_failed(&block) ⇒ Object

Registers a callback on all component channels, to be invoked when the remote server is unable to open the channel. The callback will be invoked with three arguments: the channel object that couldn’t be opened, a description of the error (as a string), and an integer code representing the error.

channel.on_open_failed do |ch, description, code|
  # ...
end


211
212
213
214
# File 'lib/net/ssh/multi/channel.rb', line 211

def on_open_failed(&block)
  channels.each { |channel| channel.on_open_failed(&block) }
  self
end

#on_process(&block) ⇒ Object

Registers a callback on all component channels, to be invoked during the idle portion of the connection event loop. The callback will be invoked with one argument: the specific channel object being processed.

channel.on_process do |ch|
  # ...
end


173
174
175
176
# File 'lib/net/ssh/multi/channel.rb', line 173

def on_process(&block)
  channels.each { |channel| channel.on_process(&block) }
  self
end

#on_request(type, &block) ⇒ Object

Registers a callback on all component channels, to be invoked when the remote server sends a channel request of the given type. The callback will be invoked with two arguments: the specific channel object receiving the request, and a Net::SSH::Buffer instance containing the request-specific data.

channel.on_request("exit-status") do |ch, data|
  puts "exited with #{data.read_long}"
end


225
226
227
228
# File 'lib/net/ssh/multi/channel.rb', line 225

def on_request(type, &block)
  channels.each { |channel| channel.on_request(type, &block) }
  self
end

#request_pty(opts = {}, &block) ⇒ Object

Perform a request_pty command on all component channels. The block, if given, is passed to each component channel, so it will (potentially) be invoked once for every channel in the collection. The block will receive two parameters: the specific channel object being operated on, and a boolean indicating whether the pty request succeeded or not.

channel.request_pty do |ch, success|
  # ...
end

See the documentation in Net::SSH for Net::SSH::Connection::Channel#request_pty for more information on how to work with the callback.



95
96
97
98
# File 'lib/net/ssh/multi/channel.rb', line 95

def request_pty(opts={}, &block)
  channels.each { |channel| channel.request_pty(opts, &block) }
  self
end

#send_data(data) ⇒ Object

Send the given data to each component channel. It will be sent to the remote process, typically being received on the process’ stdin stream.

channel.send_data "password\n"


104
105
106
107
# File 'lib/net/ssh/multi/channel.rb', line 104

def send_data(data)
  channels.each { |channel| channel.send_data(data) }
  self
end

#waitObject

Runs the connection’s event loop until the channel is no longer active (see #active?).

channel.exec "something"
channel.wait


121
122
123
124
# File 'lib/net/ssh/multi/channel.rb', line 121

def wait
  connection.loop { active? }
  self
end