简体   繁体   English

socket.io 如何通过 android 上的同步调用获得响应?

[英]How socket.io get response with synchronous call on android?

I'm writing a android chat application with socket.io-client-java.I want to check whether the client user exist at first.So I need to send a command like "user/exist" to server url and get the response from server.I need to wait the server response then can go to next step.But the socket.io use the asynchronous callback.For getting the response synchronous I known the Furture and Callable only.So I tried the way using code as below:我正在用socket.io-client-java编写一个android聊天应用程序。我想首先检查客户端用户是否存在。所以我需要向服务器url发送一个像“user/exist”这样的命令并得到响应服务器。我需要等待服务器响应然后可以进入下一步。但是socket.io使用异步回调。为了获得同步响应,我只知道Furture和Callable。所以我尝试了使用如下代码的方式:

//this is request method using socket.io
public JSONObject request(final String method,final String url,final JSONObject data){
    final JSONObject responseObj = new JSONObject();
    if (mSocket.connected()) {
             mSocket.emit(method, reqObj, new Ack() {
                @Override
                public void call(Object... objects) {
                    System.out.println("get Ack");
                    try {
                        responseObj.put("body", (JSONObject) objects[0]);
                    }catch (JSONException e){
                        e.printStackTrace();
                    }
                }
            })
         }
}
//this is Callable call implement
 @Override
    public JSONObject call(){
      return request("get","https://my-chat-server/user/exist",new JSONObject());
}

//this is call method in activity
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<JSONObject> response = executor.submit(mApiSocket);
        executor.shutdown();
        JSONObject respObj = new JSONObject();
        JSONObject respBody = new JSONObject();
        try {
            respObj = response.get();
            respBody = respObj.getJSONObject("body");
        }catch (ExecutionException e){

        }catch(InterruptedException e1){

        }catch(JSONException e2){

       }

But it dose not work.The respObj is null.但它不起作用。respObj 为空。 How can i get the reponse synchronous?我怎样才能得到同步的响应? I am a green hand on java and forgive my poor chinese english.我是java的新手,原谅我可怜的中文英语。 Any help would be appreciated!任何帮助,将不胜感激!

I known the js can use Promise and await like below:我知道 js 可以使用 Promise 并等待如下:

//request method
static request(method, url, data) {

    return new Promise((resolve, reject) => {

        this.socket.emit(method,
            {
                url: url, 
                method,
                data, 
            },
            async (res) => {
                if (res.statusCode == 100) { 
                    resolve(res.body, res); 
                } else {
                    throw new Error(`${res.statusCode} error: ${res.body}`);
                    reject(res.body, res);
                }
            }
        )

    })

}
//call method
response = await mSocket.request('get','https://my-chat-server/user/exist', {
            first_name: 'xu',
            last_name: 'zhitong',

        });

I'm not sure this is the best way but we can wait for the callback as follows:我不确定这是最好的方法,但我们可以等待回调如下:

@Nullable
Object[] emitAndWaitForAck(@NotNull String event, @Nullable Object[] args,
                           long timeoutMillis) {
    Object[][] response = new Object[1][1];
    Semaphore lock = new Semaphore(0);

    socketClient.emit(event, args, ackArgs -> {
        response[0] = ackArgs;
        lock.release();
    });

    try {
        boolean acquired = lock.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS);
        if (acquired) {
            return response[0];
        }
    } catch (InterruptedException ignored) {
    }

    return null;
}

Assuming your socket.io server returns one argument containing the body (or null) you would call it something like this:假设您的 socket.io 服务器返回一个包含正文(或 null)的参数,您可以这样称呼它:

String method = "get";
String url = "https://my-chat-server/user/exist";
long timeoutMillis = 5000;
Object[] args = emitAndWaitForAck(method, new String[]{url}, timeoutMillis);
JSONObject response = (JSONObject) args[0];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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