0
votes

so I have an app for Android that calls a webservice (C#) and I have from the start noticed that it often, but not all the time, it is extremely slow in returning an answer or that the request fails altogether.

At first I thought it had something to do with the backend code, ie the server takes to long to process the request and return a result. I have now excluded that possibility as the processing only takes about 40ms. I did however notice that the webservice code isnt called sometimes, or it takes a long time for the code to be executed.

So I started up Wireshark and took a look at the packets transferred, and discovered what I see as a faulty TCP connection phase. The first picture below show a faulty connection.

It looks like this:
Client: SYN
Server: SYN ACK
Client: SYN ACK

as this image shows:

enter image description here

But it should look like this:
Client: SYN
Server: SYN, ACK
Client: ACK

When I try another time, just calling the webservie again from the Android app (no restart or anything) I get the correct steps and also a response as expected. Here is a Wireshark-image from that: enter image description here

I am pretty sure that this is the problem with what I see as a "very slow webservice", as there is usually a long delay before receiving an answer and sometimes (as in the first image), there is no response at all. Wireshark also shows that it can just "stall" with the answers for 10-20 seconds, and that is before actually reacing the web service code.

There is no network problem, as this is all run on a local WLAN (the computer acts as a hotspot, no one else is connected to it). The Android device is a Samsung S2 running 2.3.3, the webservice is .NET 3.5 running a self-hosted ServiceHost.

Any ideas?

-------- ADDITIONAL INFO ------------

Here is how I call my webservice from the JAVA-code (Method is GET):

private void executeRequest(HttpUriRequest request, String url)
    {
        HttpClient client = new DefaultHttpClient();

        try 
        {
            httpResponse = client.execute(request);
            responseCode = httpResponse.getStatusLine().getStatusCode();
            message = httpResponse.getStatusLine().getReasonPhrase();

            HttpEntity entity = httpResponse.getEntity();

            if (entity != null) {

                InputStream instream = entity.getContent();
                response = convertStreamToString(instream);

                // Closing the input stream will trigger connection release
                instream.close();
            }

        } catch (ClientProtocolException e)  {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        } catch (IOException e) {
            client.getConnectionManager().shutdown();
            e.printStackTrace();
        }
    }

This is how the web service method is defined in .NET:

[OperationContract]
[WebGet(UriTemplate = "PutMessage?jsonString={jsonString}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat= WebMessageFormat.Json)]
string PutMessage(string jsonString);
1

1 Answers

1
votes

If you look at the dump a little closer, what you're actually seeing is the client not getting any packets from the server;

Client: SYN
Server: SYN ACK (ACK, never reaches the client)
Server: SYN ACK (Retransmission of the first ACK, also lost. )
Client: SYN (Retransmission, it does not know the server received the first SYN)
Server: SYN ACK (ACK on the SYN from the client, once again lost)
Client: SYN (Retransmission since it *still* does not know the server got the SYN)

In other words, a perfectly normal retransmission from both sides, provided the client does not receive any server packets.