Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient accessing a socket application

I started down the path of using HttpClient as I thought the service I was accessing is a REST service. Turns out it's a JSON service running on port 80 but is a socket application.

The HttpClient opens the remote port but when it sends the JSON request it never gets a response. I was having the hardest time getting fiddler to get a response back as well. But I was able to get wget and curl to send/receiving a response. That's when I talked to the original developer and he mentioned that it wasn't a true "REST" service, but just a socket application that sends/receives JSON.

Is there something I can do to tweak HttpClient to access a socket application or am I going to have to take a step back and use WebSockets?

This is the test code that sends/receives the JSON packet.

        private async Task ProcessZone(string szIPAddress)
    {
        string responseData = string.Empty;

        Uri baseAddress = new Uri(@"http://" + szIPAddress + "/player");

        try
        {
            using (var httpClient = new HttpClient { BaseAddress = baseAddress })
            {
                var _req = new SendRequest();
                _req.id = "rec-100";
                _req.url = "/stable/av/";
                _req.method = "browse";

                var _json = JsonConvert.SerializeObject(_req);

                using (var content = new StringContent(_json,Encoding.UTF8, "application/json"))
                {
                    using (var response = await httpClient.PostAsync(baseAddress, content))
                    {
                        responseData = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    }
                }
            }

            var _Response = JsonConvert.DeserializeObject<Response>(responseData);

            var item = new ZoneInfo();
            item.szIPAddress = szIPAddress;
            item.szZoneName = _Response.result.item.title;
            lstZones.Add(item);

        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }

    private async Task ProcessZones()
    {

        foreach (var item in ZoneSearch)
        {
            await ProcessZone(item.IPAddress);
        }
    }

The connection hangs on this line:

using (var response = await httpClient.PostAsync(baseAddress, content))

I should also mention that the code above does work fine on a true rest service...

like image 532
Zonus Avatar asked Sep 16 '25 16:09

Zonus


1 Answers

That's when I talked to the original developer and he mentioned that it wasn't a true "REST" service, but just a socket application that sends/receives JSON.

Knowing the protocol is the first step towards making a working client.

Is there something I can do to tweak HttpClient to access a socket application or am I going to have to take a step back and use WebSockets?

Neither, unfortunately. HttpClient - as the name implies - only works with HTTP services. Since the server is not an HTTP server, it won't work with HttpClient. WebSockets have a rather confusing name, since they are not raw sockets but instead use the WebSocket protocol, which require an HTTP handshake to set up. Since the server is not an HTTP/WebSocket server, it won't work with WebSockets.

Your only choices are to either pressure the developer to write a real REST service (which makes your job orders of magnitude easier), or use raw sockets (e.g., Socket). Correctly using raw sockets is extremely difficult, so I recommend you pressure the developer to write a REST service like the entire rest of the world does today.

like image 84
Stephen Cleary Avatar answered Sep 19 '25 04:09

Stephen Cleary