custom/InvokeAzContainerInstanceCommand_ExecuteExpanded.cs

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
 
namespace Microsoft.Azure.PowerShell.Cmdlets.ContainerInstance.Cmdlets
{
    using System;
    using System.Collections.Generic;
    using System.Net.WebSockets;
    using System.Text;
    using System.Threading.Tasks;
 
    public partial class InvokeAzContainerInstanceCommand_ExecuteExpanded : global::System.Management.Automation.PSCmdlet,
        Microsoft.Azure.PowerShell.Cmdlets.ContainerInstance.Runtime.IEventListener
    {
        /// <summary>
        /// When specified, forces the cmdlet returns last execution result when the command succeeds
        /// </summary>
        [global::System.Management.Automation.Parameter(Mandatory = false, HelpMessage = "Returns last execution result when the command succeeds. By default the cmdlet returns nothing.")]
        [global::Microsoft.Azure.PowerShell.Cmdlets.ContainerInstance.Category(global::Microsoft.Azure.PowerShell.Cmdlets.ContainerInstance.ParameterCategory.Runtime)]
        public global::System.Management.Automation.SwitchParameter PassThru { get; set; }
 
        private System.Net.WebSockets.ClientWebSocket socket;
 
        /// <summary>
        /// <c>overrideOnOk</c> will be called before the regular onOk has been processed, allowing customization of what happens
        /// on that response. Implement this method in a partial class to enable this behavior
        /// </summary>
        /// <param name="responseMessage">the raw response message as an global::System.Net.Http.HttpResponseMessage.</param>
        /// <param name="response">the body result as a <see cref="Microsoft.Azure.PowerShell.Cmdlets.ContainerInstance.Models.Api20221001Preview.IContainerExecResponse"
        /// /> from the remote call</param>
        /// <param name="returnNow">/// Determines if the rest of the onOk method should be processed, or if the method should return
        /// immediately (set to true to skip further processing )</param>
        partial void overrideOnOk(global::System.Net.Http.HttpResponseMessage responseMessage, global::System.Threading.Tasks.Task<Microsoft.Azure.PowerShell.Cmdlets.ContainerInstance.Models.Api20221001Preview.IContainerExecResponse> response, ref global::System.Threading.Tasks.Task<bool> returnNow)
        {
            var containerExecResponse = response.ConfigureAwait(false).GetAwaiter().GetResult();
            socket = new System.Net.WebSockets.ClientWebSocket();
            // Connect websocket
            socket.ConnectAsync(new System.Uri(containerExecResponse.WebSocketUri), _cancellationTokenSource.Token).ConfigureAwait(false).GetAwaiter().GetResult();
            socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(containerExecResponse.Password)), WebSocketMessageType.Text, true, _cancellationTokenSource.Token).ConfigureAwait(false).GetAwaiter().GetResult();
 
            var receiver = PullResponse();
            var sender = PushCommand();
            Task.WaitAll(sender, receiver);
            returnNow = global::System.Threading.Tasks.Task.FromResult(true);
        }
 
        private Task PullResponse()
        {
            return Task.Factory.StartNew(async () =>
            {
                string result = string.Empty;
                var allBytes = new List<byte>();
                while (WebSocketState.Open == socket.State && !this._cancellationTokenSource.Token.IsCancellationRequested)
                {
                    var rcvBuffer = WebSocket.CreateClientBuffer(4096, 4096);
                    WebSocketReceiveResult webSocketReceiveResult = await socket.ReceiveAsync(rcvBuffer, this._cancellationTokenSource.Token);
 
                    if(null != webSocketReceiveResult)
                    {
                        allBytes.AddRange(new List<byte>(rcvBuffer).GetRange(0, webSocketReceiveResult.Count));
                        if (allBytes.Count > 0 && webSocketReceiveResult.EndOfMessage)
                        {
                            result = Encoding.UTF8.GetString(allBytes.ToArray(), 0, allBytes.Count);
                            Console.Write(result);
                            allBytes.Clear();
                        }
                    }
                }
 
                if (!string.IsNullOrEmpty(result) && PassThru.ToBool()) { WriteObject(result.TrimEnd()); }
 
            }, this._cancellationTokenSource.Token).Unwrap();
        }
 
        private Task PushCommand()
        {
            return Task.Factory.StartNew(async () =>
            {
                if (Console.IsInputRedirected) return;
                 
                StringBuilder input = new StringBuilder();
                // Loop until input is entered.
                while (socket.State == WebSocketState.Open && !this._cancellationTokenSource.Token.IsCancellationRequested)
                {
                    if (Console.KeyAvailable)
                    {
                        var key = Console.ReadKey(false);
                        input.Append(key.KeyChar);
                        if (key.Key == ConsoleKey.Enter)
                        {
                            _ = socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(input.ToString())), WebSocketMessageType.Text, true, this._cancellationTokenSource.Token);
                            input.Clear();
                        }
                    }
                    System.Threading.Thread.Sleep(250);
                }
 
            }, this._cancellationTokenSource.Token).Unwrap();
 
        }
    }
}