android - 改造未正确接收响应

标签 android node.js python-3.x kotlin

我正在尝试将一个图像作为 base64 发送到 Node 服务器并接收另一个图像作为 base64 作为响应。在 Node 服务器中,图像保存在服务器目录中,并在完成 python 文件执行后发送响应。

我在将 Retrofit 与 kotlin 结合使用时遇到超时错误。当我使用 Postman 时,一切都运行良好。

这是 Retrofit 创建代码:

var  okHttpClient: OkHttpClient =  OkHttpClient.Builder()
    .readTimeout(10, TimeUnit.MINUTES)
    .writeTimeout(10,TimeUnit.MINUTES)
    .connectTimeout(2,TimeUnit.MINUTES)
    .build();
public val retrofit = Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
    .baseUrl("http://18.191.40.41:8081/")
    .client(okHttpClient)
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build()

public val sendImageApi = retrofit.create(ApiService::class.java)

API 服务代码:

@POST("test/")
@FormUrlEncoded
@Headers("Content-Type: application/x-www-form-urlencoded")
fun sendImage(@Field("inputImage") inputImage: String): Call<ImageResponse>;

通过API发送图片的代码:

        val stream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream)
        val image = stream.toByteArray()
        var response = sendImageApi.sendImage(Base64.encodeToString(image,0))
        response.enqueue(object :Callback<ImageResponse>{
            override fun onResponse(call: Call<ImageResponse>?, response: Response<ImageResponse>?) {
                Toast.makeText(activity,response?.body()?.toString(),Toast.LENGTH_SHORT).show()
                revertBtn.visibility = View.GONE
                sendBtn.visibility = View.GONE
                openCamera.visibility = View.GONE
                val imageBytes = Base64.decode(response.toString(), 0)
                val image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
                imageView.setImageBitmap(image)
            }
            override fun onFailure(call: Call<ImageResponse>?, t: Throwable) {
                imageView.visibility=View.GONE
                Toast.makeText(activity, t.message, Toast.LENGTH_SHORT).show()
            }
        })

Node JS 服务器代码:

    var http = require('http');
    scriptPath = './imps/test.py';
    var cors = require('cors')
    const fs = require('fs');
    const files = fs.readdirSync('./');
    var Pythonshell = require('python-shell');
    var express = require('express');
    var app = express();
    var port = 8081;
    app.use(cors())

    app.use(express.static('./'));
    app.set('view engine', 'ejs');
    var bodyParser = require('body-parser');
    app.use(bodyParser.json()); // support json encoded bodies
    app.use(bodyParser.urlencoded({ extended: true ,limit: '10mb'}));
    app.use(function(req,res,next){
        res.header("Access-Control-Allow-Origin","*");
        res.header("Access-Control-Allow-Headers","Origin,X-Requested-With,Content-Type,Accept");
        next();
    });

    app.post('/test', function(req, res) {
        console.log("request received")
        img=req.body.inputImage
        fs.writeFile("./testImg/inputImage.jpg",img ,'base64', function(err) {
            if(err) {
                return console.log(err);
            }
        });

        Pythonshell.PythonShell.run(scriptPath, {args:['inputImage.jpg']}, function (err, results) {
            if (err) throw err;
            console.log(" python file called")
            console.log(results)
            var img = new Buffer(fs.readFileSync('./imps/result.png')).toString('base64');


            res.send(img);
        });

        // start the server

    });

我想接收一个字符串或对象作为包含 base64 图像的响应。

最佳答案

Use timeouts to fail a call when its peer is unreachable. Network partitions can be due to client connectivity problems, server availability problems, or anything between. OkHttp supports connect, read, and write timeouts. More Info

If you don't specify a client, Retrofit will create one with default connect and read timeouts. To set your own timeouts, you need to configure your own client and supply it to the RestAdapter.Builder.

使用 OkHttp来自 Square 的客户。

private final OkHttpClient client;

  public ConfigureTimeouts() throws Exception {
    client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();
  }

  public void run() throws Exception {
    Request request = new Request.Builder()
        .url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay.
        .build();

    try (Response response = client.newCall(request).execute()) {
      System.out.println("Response completed: " + response);
    }
  }

改造

在你的gradle中导入

implementation 'com.squareup.okhttp3:okhttp:3.12.1'

并使用OkHttpClient

final OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(60, TimeUnit.SECONDS)
        .connectTimeout(60, TimeUnit.SECONDS)
        .build();

return new Retrofit.Builder()
    .baseUrl(BuildConfig.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .client(okHttpClient)
    .build();

关于android - 改造未正确接收响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54123769/

相关文章:

javascript - Node.JS:如何等待进程完成后再继续?

JavaScript JSON 输出

android - 当我尝试从中获取数据时,ViewModel 返回清晰的对象

android - SharedViewmodel 的实例永远不会消亡吗?

java - 程序化 View 错误,不确定我做错了什么。必须调用removeView() 子级已经有父级

node.js - 如何获得可用的 Mongoose 鉴别器列表?

python - 从 "graph"(数据库)数据递归创建字典

python - Python (3.3) 包如何工作?

python-3.x - TypeError : can't pickle _thread. 锁定 Seq2Seq 中的对象

android - 如何在 TableRow 的一个单元格中添加超过 1 个 View ?