GCM(谷歌雲推送)客戶端服務器端開發全指南(服務器篇)


由於谷歌雲推送GCM升級成為FCM,所以此博客能容僅供參考 ————2016.12.2更新

今天我們按照之前所說的步驟介紹GCM雲推送服務端的開發,因為服務端的開發比客戶端的開發較簡單,遵從由易到難,一步一步攻破的原則,所以我先於客戶端講服務端的開發,話不多說,讓我們開始吧!

首先我們依舊來到首頁
這里寫圖片描述
這次我們點擊指南,進入到GCM開發Overview,這里概括了GCM客戶端服務器端開發流程。

根據以下的流程圖我們不難看出服務端和GCM的通信方式有兩種
1.Http協議
2.Xmpp協議
這里寫圖片描述

Xmpp協議常用於雙向通信,我們這里暫時不需要,因此果斷選擇Http協議來開發。

英語比較好的朋友可以看一下key的概念,這里大概介紹了google是怎么樣通過key鑒別發送者和接收者的。
不想了解的朋友只需知道我們要用到
1.Sender ID
2.API Key
3.Registration Token
就行了,然后點擊“HTTP Connection Server”開始我們的編程
這里寫圖片描述

既然選擇了http協議通信,那你必須了解http協議相關知識,這里不再闡述,有興趣的朋友可以來這里了解下推薦入手《HTTP權威指南》。

我們接着來看一下google發布的http service開發指南
這里寫圖片描述

根據上訴文章我們需要:
-設置http的鏈接為:https://gcm-http.googleapis.com/gcm/send
-設置http頭部參數:Authorization: key=YOUR_API_KEY,
-設置Content-Type:如果發送的消息是json格式,就使用Content-Type: application/json for JSON; 如果是純文本(比如說一條String字符串)就使用Content-Type:application/x-www-form-urlencoded;charset=UTF-8

其實他這里可能漏了兩個參數,一個是http方法 Method 和 Sender ID,Method 是使用http一般都要設置的參數,我們這里使用“post”方法,Sender ID就真的是一個坑了,一開始樓主並不知道有這個參數,怎么發消息都發布出去,問了下有經驗的大神才知道Sender ID也要給上才行的。

然后這里說一下,服務端的開發我選擇使用.net,不得不說,.net對於一些大型項目的支持真的很好,就是VS比較重量級,不是處處可以布置,也許你會喜歡使用java來寫,但是個人感覺面向對象編程語言的邏輯是相同的,樓主一開始學習的是java,然后因為需求兼顧了.net的開發,再后來使用的objective-c,使用起來邏輯並不會出現沖突的情況,頂多就是API和語法個別地方有些不一樣,使用起來不是很熟手而已。所以看了我用.net寫的服務端程序,你一定很快就能用java copy出來的。

接着就是激動人心的時刻——————上代碼!

//建立一個http鏈接並設置http頭部參數
WebRequest gcmRequest;
gcmRequest = WebRequest.Create("https://gcm-http.googleapis.com/gcm/send");
gcmRequest.Method = "post";
gcmRequest.ContentType = "application/json";
gcmRequest.Headers.Add(string.Format("Authorization: key={0}", API_KEY));
gcmRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

好了,我們接着往下看
這里寫圖片描述
這里介紹的是發送消息的格式,分別是json和純文本的格式,我們來看看json的

{ "collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4x8",
"time": "15:16.2342"
}
,
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

參數按照他所說的那樣設,要發送的消息寫在data內,然后又是一個坑爹的地方“to”,他這個to不知是不是新版本才用到的,我使用的時候他總返回400錯誤給我,google了一下,把這里的“to”改成“registration_ids”就可以了,修改后的json

{ "collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"message": "Hi lady",
"time": "15:16.2342"
}
,
"registration_ids" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

好,有格式后我們就可以開始寫Http的body部分了

 //把封裝好的json打包成byte並以流的形式發送出去
var postData = b.ToString();
System.Diagnostics.Debug.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
gcmRequest.ContentLength = byteArray.Length;
Stream dataStream = gcmRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

寫好body后就可以發送出去了

 //建立一個接收鏈接接收返回的數據
WebResponse tResponse = gcmRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();

發送出去我怎么知道他是否成功能?讓我們繼續看下去
這里寫圖片描述
這里寫圖片描述
根據說明,返回的是一組json數據,具體數據代表什么呢?我們直接去看他們返回的代碼說明,就是Downstream message error response codes

來到新的頁面后直接去看返回代碼表
這里寫圖片描述
這里寫圖片描述

這里我簡單說下幾個常見的錯誤:
1.Missing Registration Token 丟失注冊ID
-這個錯誤一般是你的注冊ID格式錯誤,或者在json上沒加雙引號,逗號之類。
2.Invalid Registration Token 無效的注冊ID
-這個錯誤一般是你ID有誤,少字母,多一橫之類的。
3.Unregistered Device 沒有注冊的設備
-這個錯誤是說你要發送的android手機沒有在google service注冊過
4.Authentication Error 認證錯誤
-這里一般會出現在你的json頭參數Authentication 設置錯誤的時候出現。
5.Mismatched Sender 不匹配的Sender ID
-Sender ID有誤
6.Invalid JSON JSON格式有誤

好了,以上幾個問題是我常遇到的,給大家做個參考。

服務器端功能的代碼就這樣寫完了,是不是很簡單?
你可以把代碼寫到webservice上去,這樣就能隨時調用了。為了方便,我直接做個簡單的頁面來實現這個功能,在源碼上有,截個實現的圖片先

這里寫圖片描述
這里返回了Invalid Registration,就是說“基友A,舍友B,多個ID英文逗號隔開”是無效的ID,這也是理所當然的,讓我們來個成功的

這里寫圖片描述

成功的話他會返回成功ID,就不會有上面的錯誤代碼出現。

以下是功能所有代碼:

    public partial class WebForm1 : System.Web.UI.Page
{
private string API_KEY = "你服務器的api——key";
private string SENDER_ID = "你的senderID";

protected void Page_Load(object sender, EventArgs e)
{

}

protected void Button1_Click(object sender, EventArgs e)
{
var message = TextBox1.Text;
var regID = TextBox2.Text;
String[] regIDAll = new String[] { };
regIDAll = regID.Split(',');

//對ID進行雙引號的添加
if (regIDAll.Length > 1)
{
regID = "";
for (int i = 0; i < regIDAll.Length; i++)
{
if (i == 0)
{
regIDAll[i] = "\"" + regIDAll[i] + "\"";
}
else
{
regIDAll[i] = ",\"" + regIDAll[i] + "\"";
}
regID = regID + regIDAll[i];
}
}
else
{
regID = "\"" + regID + "\"";
}


//建立一個http鏈接並設置http頭部參數
WebRequest gcmRequest;
gcmRequest = WebRequest.Create("https://gcm-http.googleapis.com/gcm/send");
gcmRequest.Method = "post";
gcmRequest.ContentType = "application/json";
gcmRequest.Headers.Add(string.Format("Authorization: key={0}", API_KEY));
gcmRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

//封裝發送消息參數成json
StringBuilder b = new StringBuilder();
b.Append("{");
b.Append("\"collapse_key\":\"score_update\",");
b.Append("\"time_to_live\": 108,");
b.Append("\"delay_while_idle\": true,");
b.Append("\"data\": {");
b.Append("\"message\": \"" + message + "\",");
b.Append("\"time\": \"" + System.DateTime.Now.ToString() + "\",");
b.Append(" }");
b.Append("\"registration_ids\": [");
b.Append(regID);
b.Append("]");
b.Append("}");

//把封裝好的json打包成byte並以流的形式發送出去
var postData = b.ToString();
System.Diagnostics.Debug.WriteLine(postData);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
gcmRequest.ContentLength = byteArray.Length;
Stream dataStream = gcmRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();


//建立一個接收鏈接接收返回的數據
WebResponse tResponse = gcmRequest.GetResponse();
dataStream = tResponse.GetResponseStream();
StreamReader tReader = new StreamReader(dataStream);
String sResponseFromServer = tReader.ReadToEnd();

//直接在label顯示返回的結果
Label1.Text = "result: " + sResponseFromServer;

tReader.Close();
dataStream.Close();
tResponse.Close();
}
}
}

以下是我頁面的代碼:

<!--注意!!這是APS.NET的代碼,要在html文件上運行要稍加修改!!-->


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="css/AndroidPush.css" rel="Stylesheet" type="text/css" />
</head>
<body>
<form id="Form1" runat=server>
<div class="t-box">
<div class="box_1">
<div class="t-con">
<img src="logo.png" alt="" />
<div class="abs-box">
<div class="con-box">
<div class="con">
<asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Wrap=true Text="這里輸入發送的消息"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server" TextMode="MultiLine" Wrap=true Text="這里輸入設備在GCM注冊的ID,多個注冊ID逗號分開"></asp:TextBox>
<div class="result">
<asp:Label ID="Label1" runat="server" Text="result:"></asp:Label>
</div>
<div class="operation"><asp:Button ID="Button1" runat="server" Text="Send"
onclick="Button1_Click" />
</div>

</div>
</div>
</div>
</div>
</div>
</div>
</form>
</body>
</html>

最后是萬眾期待的源碼!!!!!

源碼在此,請叫我雷鋒


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com