谷歌云通讯在设备间不可靠?切换到其他协议或其他服务


Google cloud messaging unreliable between devices? Switch to other protocol or other service?

我在一个基于设备之间实时通信的应用程序上工作了几天。在过去,我使用OkHttp库通过POST方法使用GCM进行通知。到目前为止,一切顺利。

但是当涉及到实时通信时,我面临着很多关于连接超时甚至消息从未传递的问题。

我的实现很简单。首先,用户从他的手机通过POST和我的在线服务器向另一个手机(驱动程序)发送请求,然后确认请求并通过另一个POST方法和在线服务器回复发送者。

但是只有大约80%的回复返回给用户,或者他们在几分钟后到达。

问题可能在我的实现??或者我应该切换到GCM云连接服务器(XMPP)??

我非常需要一些建议,请点亮我。问候。

Php实现:

<?php
include_once '../includes/db_connect.php'; 
// Query database for driver's regId
 if(!empty($_POST["str"])) { 
    $sql = "SELECT * FROM DRIVERS WHERE NAME = '$_POST[driver]' " ;
    $result = mysqli_query($mysqli, $sql);
    $row = mysqli_fetch_assoc($result); 
    $gcmRegID  = $row["REGID"]; 
    $clientId = $_POST["clientId"]; 
    $street = $_POST["str"]; 
    $number = $_POST["nr"]; 
    $bloc = $_POST["bl"]; 
    $scara = $_POST["sc"]; 
    if (isset($gcmRegID)) {    
      $gcmRegIds = array($gcmRegID);
      $message = array("jstr" => $street, "jnr" => $number, "jbl" => $bloc, "jsc" => $scara, "jId" => $clientId); 
      $pushStatus = sendPushNotificationToGCM($gcmRegIds, $message);
    }   
 }
  // Reply to the client if available or not
  if(!empty($_POST["response"])) { 
     $gcmRegID  = $_POST["clientId"]; 
     $response = $_POST["response"];      
      $gcmRegIds = array($gcmRegID);
      $message = array("jresp" => $response); 
      $pushStatus = sendPushNotificationToGCM($gcmRegIds, $message);
 }
  //generic php function to send GCM push notification
   function sendPushNotificationToGCM($registatoin_ids, $message) {
    //Google cloud messaging GCM-API url
        $url = 'https://android.googleapis.com/gcm/send';
        $fields = array(
            'registration_ids' => $registatoin_ids,
            'data' => $message
        );
    // Google Cloud Messaging GCM API Key
    define("GOOGLE_API_KEY", "**************");    
        $headers = array(
            'Authorization: key=' . GOOGLE_API_KEY,
            'Content-Type: application/json'
        );
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); 
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        $result = curl_exec($ch);       
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }
        curl_close($ch);
        return $result;
    }
?>

Order Activity—用于向驱动程序发送请求

public void callDriver (View view){
    MySendTask send = new MySendTask();
    send.execute();
    Toast.makeText(getApplicationContext(), "Button Pressed :)", 
            Toast.LENGTH_SHORT).show();
}
private class MySendTask extends AsyncTask<String, String, String> {
    @Override
        protected void onPreExecute() {
        progressb.setVisibility(View.VISIBLE);
        }

@Override
protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
String str = streetName.getText().toString();
String nr = streetNr.getText().toString();
String bl = bloc.getText().toString();
String sc = scara.getText().toString();     
SharedPreferences prefs = getSharedPreferences("Notification", MODE_PRIVATE);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");   

    try {
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(10000, TimeUnit.MILLISECONDS);
            RequestBody formBody = new FormEncodingBuilder()
            .add("clientId", registrationId)
            .add("driver", "Peter Bleul")
            .add("str", str)
            .add("nr", nr)
            .add("bl", bl)
            .add("sc", sc)
            .build();
            Request request = new Request.Builder()
            .url("http://edmon.net/andr/index.php")
            .post(formBody)
            .build();
            Response response = client.newCall(request).execute();
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            System.out.println(response.body().string());               

            } catch (Exception e) {
                e.printStackTrace();
            }                   
                return null;
            }               
            @Override
            protected void onPostExecute(String result) {
                Toast.makeText(getApplicationContext(), "Order successfully sent!", 
                        Toast.LENGTH_SHORT).show();
                progressb.setVisibility(View.INVISIBLE);
            }
        }

}

GCM不保证消息传递。GCM还限制消息传递,这通常会导致严重的延迟。有关此主题的更多详细信息,请参阅:http://developer.android.com/google/gcm/adv.html(转到"消息的生命周期"部分)。

我在我工作的应用程序中遇到了类似的问题。

因此,GCM似乎不是实时通信的好选择。

我找到了一个很好的例子,用很好的示例应用程序很好地解释了这个过程,感谢:Antoine Cambell

我建议每个人在回答类似的问题时都这样做。