web-dev-qa-db-ja.com

Asp.NetによるGCMプッシュ通知

ご覧のように、Googleはプッシュ通知システムを移行しています。

http://developer.Android.com/guide/google/gcm/c2dm.html

Asp.Netアプリケーションを使用してGoogleクラウドメッセージング(GCM)を実装するために利用できるサンプルまたはガイドラインはありますか?

17
Nikunj Ganatra

私には問題なく機能し、役立つ可能性があるコードがあります。テストしてみました...

void send(string regId)
{
    var applicationID = "xxxxxxxx";


    var SENDER_ID = "xxxxx";
    var value = txtMsg.Text;
    WebRequest tRequest;
    tRequest = WebRequest.Create("https://Android.googleapis.com/gcm/send");
    tRequest.Method = "post";
    tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
    tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));

    tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

    // string postData = "{ 'registration_id': [ '" + regId + "' ], 'data': {'message': '" + txtMsg.Text + "'}}";
    string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + regId + "";
    Console.WriteLine(postData);
    Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
    tRequest.ContentLength = byteArray.Length;

    Stream dataStream = tRequest.GetRequestStream();
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();

    WebResponse tResponse = tRequest.GetResponse();

    dataStream = tResponse.GetResponseStream();

    StreamReader tReader = new StreamReader(dataStream);

    String sResponseFromServer = tReader.ReadToEnd();

    lblStat.Text = sResponseFromServer;
    tReader.Close();
    dataStream.Close();
    tResponse.Close();
}
9
user1551788

これがc#のコードです

 WebRequest tRequest;
        tRequest = WebRequest.Create("https://Android.googleapis.com/gcm/send");
        tRequest.Method = "post";
        tRequest.ContentType = "application/x-www-form-urlencoded";
        tRequest.Headers.Add(string.Format("Authorization: key={0}", GoogleAppID));
String collaspeKey = Guid.NewGuid().ToString("n");
String postData=string.Format("registration_id={0}&data.payload={1}&collapse_key={2}", DeviceID, "Pickup Message" + DateTime.Now.ToString(), collaspeKey);
Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;

Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

WebResponse tResponse = tRequest.GetResponse();

dataStream = tResponse.GetResponseStream();

StreamReader tReader = new StreamReader(dataStream);

String sResponseFromServer = tReader.ReadToEnd();

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

しばらく前から、C2DMをいじってプッシュ通知を送信していました。このページに記載されている変更に従ってコードを変更しました http://developer.Android.com/guide/google/gcm/c2dm.html#server GCMサービスを利用するために:

Private Sub btnPush_Click(sender As Object, e As System.EventArgs) Handles btnPush.Click
    lblResponse.Text = SendNotification(AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA)
End Sub

私のSendNotification関数:

Private Function SendNotification(ByVal authstring As String) As String
    ServicePointManager.ServerCertificateValidationCallback = Function(sender As Object, certificate As X509Certificate, chain As X509Chain, sslPolicyErrors As SslPolicyErrors) True
    Dim request As WebRequest = WebRequest.Create("https://Android.googleapis.com/gcm/send")
    request.Method = "POST"
    request.ContentType = "application/x-www-form-urlencoded"
    request.Headers.Add(String.Format("Authorization: key={0}", authstring))
    Dim collaspeKey As String = Guid.NewGuid().ToString("n")
    Dim postData As String = String.Format("registration_id={0}&data.payload={1}&collapse_key={2}", deviceList.SelectedValue, txtPayload.Text, collaspeKey)
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
    request.ContentLength = byteArray.Length
    Dim dataStream As Stream = request.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()
    Dim response As WebResponse = request.GetResponse()
    dataStream = response.GetResponseStream()
    Dim reader As New StreamReader(dataStream)
    Dim responseFromServer As String = reader.ReadToEnd()
    reader.Close()
    dataStream.Close()
    response.Close()

    Return responseFromServer
End Function

GCMでは、認証キーを取得するためにGoogleに対して認証する必要がないようです(C2DMの場合と同様)。代わりに、SendNotification関数に渡されるAPIキーが必要です。このページは、APIキーを設定するのに役立ちます: http://developer.Android.com/guide/google/gcm/gs.html

念のため、私のWebフォームのコードを以下に示します。

<form id="form1" runat="server">
<div>
    <asp:DropDownList ID="deviceList" runat="server">
        <asp:ListItem Value="device-id-goes-here">Eclipse AVD</asp:ListItem>
        <asp:ListItem Value="device-id-goes-here">My Phone 1</asp:ListItem>
        <asp:ListItem Value="device-id-goes-here">My Phone 2</asp:ListItem>
    </asp:DropDownList>
    <br /><br />
    <asp:TextBox ID="txtPayload" runat="server" Width="480px"></asp:TextBox>
    <br /><br />
    <asp:Button ID="btnPush" runat="server" Text="Push" />
    <asp:Label ID="lblResponse" runat="server" Text=""></asp:Label>
</div>
</form>

Androidアプリを作成してプッシュ通知を受け取るには、このリンクをチェックしてください: http://developer.Android.com/guide/google/gcm/gs.html# Androidアプリ

System.Net、System.IO、System.Security.Cryptography.X509CertificatesおよびSystem.Net.Securityをインポートすることを忘れないでください。

3
Zishan

JSONウェイ

user1551788の回答は問題なく機能しますが、JSONで実行するのが好きです。1行にすべてを挿入するよりも、これをお勧めします。

内部クラス「jsonObj」は、ドキュメントに必要なものと同じです。実行できるさまざまなリクエストを確認してください here

簡単な説明:

to:送信先の電話。電話から受信したregistrationIdをここに挿入します。 delay_while_idledelay_while_idleフラグを使用すると、デバイスがアクティブになると通知が配信されます。 (ロックされていない、ユーザーが実際に電話を使用するとき)。

data:カスタムキーと値のペアでdataを設定し、追加のペイロードをクライアントアプリに渡します。したがって、4 KBを超えない限り、別のオブジェクトを含むjson文字列が必要な場合は、任意の変数を入力できます。

私が使用しなかったものもあります。

collapse_key:設定されている場合、同じcollapse_key名前は古い通知を上書きする必要があります(通知が送信されたときに電話側で適切に実装されている方が良いです。GCMサーバーでは、通知が保留されているときに上書きされます)。

time_to_live:単純に、通知が存続する時間の長さで、現在IOSではサポートされていません。

その他、ドキュメントを参照してください。

私のクラスの外でそのオブジェクトを必要としなかったので、内部クラス。何であれ、「データ」のような名前を付けるのに適しています。

private void SendPostsToGCM(jsonObj jsonObj)
    {            
        string senderId = "your project number (google)";
        string apiKey = "your apiKey, found on console";

        WebRequest tRequest;
        tRequest = WebRequest.Create("https://Android.googleapis.com/gcm/send");
        tRequest.Method = "post";

        tRequest.ContentType = "application/json";
        tRequest.Headers.Add(string.Format("Authorization: key={0}", apiKey));
        tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));

        string jsonPostData = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj); //download Newtonsoft NuGet package

        Byte[] byteArray = Encoding.UTF8.GetBytes(jsonPostData);
        tRequest.ContentLength = byteArray.Length;

        Stream dataStream = tRequest.GetRequestStream();
        dataStream.Write(byteArray, 0, byteArray.Length);
        dataStream.Close();
        WebResponse tResponse = tRequest.GetResponse();
        dataStream = tResponse.GetResponseStream();
        StreamReader tReader = new StreamReader(dataStream);
        String sResponseFromServer = tReader.ReadToEnd();

        string response = sResponseFromServer;
        tReader.Close();
        dataStream.Close();
        tResponse.Close();
    }

    internal class jsonObj
    {
        public bool delay_while_idle { get; set; }
        public data data { get; set; }
        public string to { get; set; }
    }

    internal class data
    {
        public int Id { get; set; }
        public string text { get; set; }
    }

使用するには、単に:

    //some filtering to select some posts or whatever.
    jsonObj jsonPostData = new jsonObj()
    {
        delay_while_idle = true,
        to = registrationGCMid,
        data = new data()
        {
            Id = post.id,
            text = post.text,
        }
    };
SendPostsToGCM(jsonPostData);

私が気付いたもう1つの大きな違いは、googleサービスが有用な情報を含むjson文字列を返し、成功した数と失敗した数などを通知することです。

2
CularBytes

Nikunj Ganatra、このリンクでエラーの種類を確認できます。アプリケーションIDが間違っているか、他の詳細が正しくない可能性があります。 http://developer.Android.com/guide/google/gcm/ gcm.html#top

応答/説明

200メッセージは正常に処理されました。応答の本文にはメッセージステータスの詳細が含まれますが、その形式は、リクエストがJSONかプレーンテキストかによって異なります。詳細については、成功応答の解釈を参照してください。

400 JSONリクエストにのみ適用されます。リクエストをJSONとして解析できなかったか、リクエストに無効なフィールドが含まれていたことを示します(たとえば、数値が期待される場所に文字列を渡した)。正確な失敗理由は応答に記載されており、要求を再試行する前に問題に対処する必要があります。

401送信者アカウントの認証中にエラーが発生しました。

500リクエストの処理中にGCMサーバーで内部エラーが発生しました。

503サーバーが一時的に利用不可であることを示します(タイムアウトなどのため)。送信者は、応答に含まれるすべてのRetry-Afterヘッダーを尊重して、後で再試行する必要があります。アプリケーションサーバーは、指数バックオフを実装する必要があります。 GCMサーバーがリクエストを処理するのに時間がかかりすぎました。

修正しました。

0
user1528505