Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

178
Vistas
Retrofit Not Receiving Responses After the First

I am using RetroFit on android in order to send images to a REST server (developed using Python and Flask). The app sends a first image to the server which stores it and that returns that image's ID to the client. The client then takes another photo and sends it to the server, this time with the previous image ID in the endpoint URL. The server should then compute the rotation from image A to image B and return the result. Once the client has sent the second image, it should repeatedly poll the endpoint for a result until the calculations are completed server side.

The first image sends correctly, and the server stores it. The client then correctly receives the response from the server. The problem occurs when the client sends the second image. The server receives the POST correctly, but the client never seems to get a response. This is also true of the third message, the GET request that polls for a result, it is received by the server but the client never sees a response.

The code for my REST server is here

class Image(Resource):
    def post(self):
        file = request.files['uploaded_file']
        centerX = request.form['center_x']
        centerY = request.form['center_y']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], str(id(True)) + ".jpg"))
            result = {'id' : id(), 'error' : True, 'result' : 5.5}
            return jsonify(result)
        else:
            return {'id' : -1, 'error' : False}

class Find_Transform(Resource):
    def post(self, first_id):
        result = {'id' : 1, 'error' : True, 'result' : 1.2}
        return jsonify(result)

class Find_Transform_Result(Resource):
    def get(self, first_id, second_id):
        print("Hello")
        result = {'id' : 0, 'error' : True, 'result' : 1.1}
        return jsonify(result)


api.add_resource(Image,'/image')
api.add_resource(Find_Transform,'/image/<first_id>/find-transform')
api.add_resource(Find_Transform_Result, '/image/<first_id>/find-transform/<second_id>')

if __name__ == '__main__':
    app.run(host='0.0.0.0',port='5002')

As you can see some of the endpoints are still just stubs to test the REST api.

My java Respond.class is here

public class Respond {

    private int id;
    private Boolean error;
    private float result;

    public int getMessage() {
        return id;
    }


    public void setMessage(int id) {
        this.id = id;
    }

    public Boolean getError() {
        return error;
    }

    public void setError(Boolean error) {
        this.error = error;
    }

    public void setResult(float result) {
        System.out.println("Got Result");
        this.result = result;
    }

    public float getResult() {
        return result;
    }
}

My Retrofit interface is here

public interface FileApi {

    @Multipart
    @POST("/image")
    Call<Respond> uploadCropImage(@Part MultipartBody.Part file, @Part MultipartBody.Part x, @Part MultipartBody.Part y);

    @Multipart
    @POST("/image/{first_id}/find-transform")
    Call<Respond> uploadCompareImage(@Path("first_id") int id, @Part MultipartBody.Part file);

    @GET("/image/{first-id}/find-transform/{second-id}")
    Call<Respond> getCompareResult(@Path("first-id") int firstId, @Path("second-id") int secondId);
}

The reason for the two separate file upload functions is that the first image needs to be sent alongside a user selected centre point, while the second is just an image.

Finally the sections where I build my requests are here:

 private void uploadFirstImage(byte[] imageBytes) {

        FileApi service = RetroClient.getApiService();


        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageBytes);

        MultipartBody.Part fileBody =
                MultipartBody.Part.createFormData("uploaded_file", "first_image.jpg", requestFile);


        RequestBody image_center_x = RequestBody.create(MediaType.parse("multipart/form-data"), Float.toString(points[0].x));
        MultipartBody.Part xBody = MultipartBody.Part.createFormData("center_x", null, image_center_x);

        RequestBody image_center_y = RequestBody.create(MediaType.parse("multipart/form-data"), Float.toString(points[0].y));
        MultipartBody.Part yBody = MultipartBody.Part.createFormData("center_y", null, image_center_y);


        Call<Respond> resultCall = service.uploadCropImage(fileBody, xBody, yBody);

        resultCall.enqueue(new Callback<Respond>() {
            @Override
            public void onResponse(Call<Respond> call, Response<Respond> response) {

                // Response Success or Fail
                if (response.isSuccessful()) {
                    if (response.body().getError()==true){
                        System.out.println(Double.toString(response.body().getResult()));
                        session_id = response.body().getMessage();
                    }


                } else {
                    Toast.makeText(getApplicationContext(),"Failed to communicate with server",Toast.LENGTH_LONG).show();
                }


            }

            @Override
            public void onFailure(Call<Respond> call, Throwable t) {
            }
        });
    }

and here:

private void uploadSecondImage(byte[] imageBytes) {

        FileApi service = RetroClient.getApiService();


        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageBytes);

        MultipartBody.Part fileBody =
                MultipartBody.Part.createFormData("uploaded_file", "first_image.jpg", requestFile);


        Call<Respond> resultCall = service.uploadCompareImage(session_id,fileBody);

        resultCall.enqueue(new Callback<Respond>() {
            @Override
            public void onResponse(Call<Respond> call, Response<Respond> response) {

                // Response Success or Fail
                if (response.isSuccessful()) {
                    if (response.body().getError()==true){
                        System.out.println("Got Second Response");
                        resultID = response.body().getMessage();
                    }


                } else {
                    Toast.makeText(getApplicationContext(),"Failed to communicate with server",Toast.LENGTH_LONG).show();
                }


            }

            @Override
            public void onFailure(Call<Respond> call, Throwable t) {
                System.out.println("Failure");
            }
        });
    }

and finally, for the GET request

    final boolean[] resultReady = {false};
    while (!resultReady[0]) {

        FileApi service = RetroClient.getApiService();
        Call<Respond> resultCall = service.getCompareResult(session_id, resultID);
        resultCall.enqueue(new Callback<Respond>() {
            @Override
            public void onResponse(Call<Respond> call, Response<Respond> response) {

                // Response Success or Fail
                if (response.isSuccessful()) {
                    if (response.body().getError()){
                        System.out.println("Got Response");
                        resultReady[0] = true;
                        theta[0] = response.body().getResult();
                        Toast.makeText(getApplicationContext(),"Measurement Recieved",Toast.LENGTH_LONG).show();
                    }
                    else {
                        Toast.makeText(getApplicationContext(),"Error Recieved",Toast.LENGTH_LONG).show();
                    }


                } else {
                    Toast.makeText(getApplicationContext(),"Failed to communicate with server",Toast.LENGTH_LONG).show();
                }


            }

            @Override
            public void onFailure(Call<Respond> call, Throwable t) {
            }
        });



    }

I've tried putting breakpoints in the OnResponse functions, and have put debug statements in both OnResponse and OnFailure and it seems that that code is never run. What could be going wrong here?

EDIT: Okay so I've got some logging data. I've tested the server from a python console

In [1]: import requests

In [2]: requests.get("http://localhost:5002/image/1/find-transform/2")
Out[2]: <Response [200]>

In [3]: _.text
Out[3]: '{"error": true, "id": 0, "result": 1.1}'

In [4]: requests.post("http://localhost:5002/image/find-transform")
Out[4]: <Response [404]>

In [5]: requests.post("http://localhost:5002/image/1/find-transform")
Out[5]: <Response [200]>

In [6]: _.text
Out[6]: '{"error": true, "id": 1, "result": 1.2}'

I also put the http logging in the client side as suggested by a comment, which gave this logging output.

D/OkHttp: --> POST http://192.168.0.19:5002/image
    Content-Type: multipart/form-data; boundary=bc4ae771-2762-4124-8f07-d00dc925d886
D/OkHttp: Content-Length: 2044497
D/OkHttp: --bc4ae771-2762-4124-8f07-d00dc925d886
    Content-Disposition: form-data; name="uploaded_file"; filename="first_image.jpg"
    Content-Type: multipart/form-data
    Content-Length: 2043935
    (Truncated raw image data)
V/RenderScript: 0x7f77b4c000 Launching thread(s), CPUs 8
D/OkHttp: <-- 200 OK http://192.168.0.19:5002/image (410ms)
    Content-Type: application/json
    Content-Length: 39
    Server: Werkzeug/0.14.1 Python/3.6.8
    Date: Wed, 24 Jul 2019 17:00:47 GMT
D/OkHttp: {"error": true, "id": 9, "result": 5.5}
    <-- END HTTP (39-byte body)
I/System.out: 5.5
W/ImageReader_JNI: Unable to acquire a lockedBuffer, very likely client tries to lock more than maxImages buffers
I/System.out: Resultcall
D/OkHttp: --> POST http://192.168.0.19:5002/image/9/find-transform
    Content-Type: multipart/form-data; boundary=63de36cb-0961-4802-a97f-57b98ebcd8cb
D/OkHttp: Content-Length: 1655614
D/OkHttp: --63de36cb-0961-4802-a97f-57b98ebcd8cb
    Content-Disposition: form-data; name="uploaded_file"; filename="first_image.jpg"
    Content-Type: multipart/form-data
    Content-Length: 1655386
    (Truncated raw image data)
D/OkHttp: <-- HTTP FAILED: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
D/OkHttp: --> GET http://192.168.0.19:5002/image/9/find-transform/-1
    --> END GET
D/OkHttp: <-- 200 OK http://192.168.0.19:5002/image/9/find-transform/-1 (90ms)

It seems that the server is both correctly receiving the request, and sending the correct response. So something must be failing to be processed correctly client side, but I can't think what.

over 4 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda