我在一个基于设备之间实时通信的应用程序上工作了几天。在过去,我使用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
我建议每个人在回答类似的问题时都这样做。