9
9
10
10
namespace k8s
11
11
{
12
+ /// <summary>
13
+ /// <para>
14
+ /// The <see cref="StreamDemuxer"/> allows you to interact with processes running in a container in a Kubernetes pod. You can start an exec or attach command
15
+ /// by calling <see cref="Kubernetes.WebSocketNamespacedPodExecAsync(string, string, IEnumerable{string}, string, bool, bool, bool, bool, Dictionary{string, List{string}}, CancellationToken)"/>
16
+ /// or <see cref="Kubernetes.WebSocketNamespacedPodAttachAsync(string, string, string, bool, bool, bool, bool, Dictionary{string, List{string}}, CancellationToken)"/>. These methods
17
+ /// will return you a <see cref="WebSocket"/> connection.
18
+ /// </para>
19
+ /// <para>
20
+ /// Kubernetes 'multiplexes' multiple channels over this <see cref="WebSocket"/> connection, such as standard input, standard output and standard error. The <see cref="StreamDemuxer"/>
21
+ /// allows you to extract individual <see cref="Stream"/>s from this <see cref="WebSocket"/> class. You can then use these streams to send/receive data from that process.
22
+ /// </para>
23
+ /// </summary>
12
24
public class StreamDemuxer : IDisposable
13
25
{
14
26
private readonly WebSocket webSocket ;
15
27
private readonly Dictionary < byte , ByteBuffer > buffers = new Dictionary < byte , ByteBuffer > ( ) ;
16
28
private readonly CancellationTokenSource cts = new CancellationTokenSource ( ) ;
17
29
private Task runLoop ;
18
30
31
+ /// <summary>
32
+ /// Initializes a new instance of the <see cref="StreamDemuxer"/> class.
33
+ /// </summary>
34
+ /// <param name="webSocket">
35
+ /// A <see cref="WebSocket"/> which contains a multiplexed stream, such as the <see cref="WebSocket"/> returned by the exec or attach commands.
36
+ /// </param>
19
37
public StreamDemuxer ( WebSocket webSocket )
20
38
{
21
39
this . webSocket = webSocket ?? throw new ArgumentNullException ( nameof ( webSocket ) ) ;
22
40
}
23
41
24
42
public event EventHandler ConnectionClosed ;
25
43
44
+ /// <summary>
45
+ /// Starts reading the data sent by the server.
46
+ /// </summary>
26
47
public void Start ( )
27
48
{
28
49
this . runLoop = this . RunLoop ( this . cts . Token ) ;
29
50
}
30
51
52
+ /// <inheritdoc/>
31
53
public void Dispose ( )
32
54
{
33
55
try
@@ -45,6 +67,35 @@ public void Dispose()
45
67
}
46
68
}
47
69
70
+ /// <summary>
71
+ /// Gets a <see cref="Stream"/> which allows you to read to and/or write from a remote channel.
72
+ /// </summary>
73
+ /// <param name="inputIndex">
74
+ /// The index of the channel from which to read.
75
+ /// </param>
76
+ /// <param name="outputIndex">
77
+ /// The index of the channel to which to write.
78
+ /// </param>
79
+ /// <returns>
80
+ /// A <see cref="Stream"/> which allows you to read/write to the requested channels.
81
+ /// </returns>
82
+ public Stream GetStream ( ChannelIndex ? inputIndex , ChannelIndex ? outputIndex )
83
+ {
84
+ return GetStream ( ( byte ? ) inputIndex , ( byte ? ) outputIndex ) ;
85
+ }
86
+
87
+ /// <summary>
88
+ /// Gets a <see cref="Stream"/> which allows you to read to and/or write from a remote channel.
89
+ /// </summary>
90
+ /// <param name="inputIndex">
91
+ /// The index of the channel from which to read.
92
+ /// </param>
93
+ /// <param name="outputIndex">
94
+ /// The index of the channel to which to write.
95
+ /// </param>
96
+ /// <returns>
97
+ /// A <see cref="Stream"/> which allows you to read/write to the requested channels.
98
+ /// </returns>
48
99
public Stream GetStream ( byte ? inputIndex , byte ? outputIndex )
49
100
{
50
101
if ( inputIndex != null && ! this . buffers . ContainsKey ( inputIndex . Value ) )
@@ -60,6 +111,53 @@ public Stream GetStream(byte? inputIndex, byte? outputIndex)
60
111
return new MuxedStream ( this , inputBuffer , outputIndex ) ;
61
112
}
62
113
114
+ /// <summary>
115
+ /// Directly writes data to a channel.
116
+ /// </summary>
117
+ /// <param name="index">
118
+ /// The index of the channel to which to write.
119
+ /// </param>
120
+ /// <param name="buffer">
121
+ /// The buffer from which to read data.
122
+ /// </param>
123
+ /// <param name="offset">
124
+ /// The offset at which to start reading.
125
+ /// </param>
126
+ /// <param name="count">
127
+ /// The number of bytes to read.
128
+ /// </param>
129
+ /// <param name="cancellationToken">
130
+ /// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
131
+ /// </param>
132
+ /// <returns>
133
+ /// A <see cref="Task"/> which represents the asynchronous operation.
134
+ /// </returns>
135
+ public Task Write ( ChannelIndex index , byte [ ] buffer , int offset , int count , CancellationToken cancellationToken = default ( CancellationToken ) )
136
+ {
137
+ return Write ( ( byte ) index , buffer , offset , count , cancellationToken ) ;
138
+ }
139
+
140
+ /// <summary>
141
+ /// Directly writes data to a channel.
142
+ /// </summary>
143
+ /// <param name="index">
144
+ /// The index of the channel to which to write.
145
+ /// </param>
146
+ /// <param name="buffer">
147
+ /// The buffer from which to read data.
148
+ /// </param>
149
+ /// <param name="offset">
150
+ /// The offset at which to start reading.
151
+ /// </param>
152
+ /// <param name="count">
153
+ /// The number of bytes to read.
154
+ /// </param>
155
+ /// <param name="cancellationToken">
156
+ /// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
157
+ /// </param>
158
+ /// <returns>
159
+ /// A <see cref="Task"/> which represents the asynchronous operation.
160
+ /// </returns>
63
161
public async Task Write ( byte index , byte [ ] buffer , int offset , int count , CancellationToken cancellationToken = default ( CancellationToken ) )
64
162
{
65
163
byte [ ] writeBuffer = ArrayPool < byte > . Shared . Rent ( count + 1 ) ;
0 commit comments