简体   繁体   中英

Is it possible to listen response from HTTP server during writing data to request stream in .Net console app?

I have the Http server (written in D lang) with endpoint for POST method. I want to stream some commands to that method from my non web client written in .Net, and durring that streaming it would be good for me to listen also for response from this server in case something went wrong. And here is the problem, it seems that I should end streaming (or send zero tcp message) to get any response.

Thanks for Wireshark I know that it behaves like this:

  • I send message to server with headers
  • Server answer me with ACK
  • Next, I send my message with some coordinates
    • "18\\r\\n[{"x":0.5,"y":0.5,"z":0}\\r\\n"
  • Server answer with ACK and HTTP Continue status
  • Then I stream some commands to server and it answer me with ACK for each command
  • Next, I wait a little bit, the server send me HTTP Request Time-out. BUT, my application will not get this and would think that everything is fine.

One version of implementation:

        public async Task Start()
        {
            httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;

            var json = GetData();

            StreamWriter writer = null;
            var content = new PushStreamContent(async (stream, httpContent, transportContext) =>
            {
                writer = new StreamWriter(stream);
                writer.AutoFlush = true;
                await writer.WriteLineAsync("[" + json);
            });
            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var message = new HttpRequestMessage(HttpMethod.Post, url);
            message.Content = content;

            Task.Run(async () =>
            {
                var result = await httpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead);
                Console.WriteLine(result.StatusCode);
            });


            while (true)
            {
                if(Console.ReadKey().KeyChar == 'a')
                {
                    await writer.WriteLineAsync($",{json}");
                }
            }
        }

Your scenario looks a good match for SignalR.

Basically, SignalR is an open-source library that simplifies adding real-time web functionality to apps. Real-time web functionality enables server-side code to push content to clients instantly.

You can find a sample using SignalR 2 with non-Core version bellow:

First, create the following basic structure in server side:

   public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }

Now you need to create the following structure in client side:

    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-3.1.1.min.js" ></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="signalr/hubs"></script>
    <!--Add script to update the page and send messages.--> 
    <script type="text/javascript">
        $(function () {
            // Declare a proxy to reference the hub. 
            var chat = $.connection.chatHub;
            // Create a function that the hub can call to broadcast messages.
            chat.client.broadcastMessage = function (name, message) {
                // Html encode display name and message. 
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page. 
                $('#discussion').append('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box.  
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // Call the Send method on the hub. 
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // Clear text box and reset focus for next comment. 
                    $('#message').val('').focus();
                });
            });
        });
    </script>

You can have more info about SignalR here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM