Android 使用 Asp.Net 的 GCM 推送通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11261718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:34:19  来源:igfitidea点击:

GCM Push Notification with Asp.Net

androidasp.netpush-notificationgoogle-cloud-messaging

提问by Nikunj Ganatra

As you may have seen, Google is migrating its Push Notification System.

您可能已经看到,Google 正在迁移其推送通知系统。

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

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

Is there any sample or guide line available for implementing Google Cloud Messaging (GCM) by using an Asp.Net application?

是否有任何示例或指南可用于使用 Asp.Net 应用程序实现 Google Cloud Messaging (GCM)?

回答by user1551788

I have a piece of code which is working fine for me and could be helpful, I tested it out...

我有一段代码对我来说工作正常并且可能会有所帮助,我对其进行了测试...

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();
}

回答by Steve The Sultan

here is the code in c#

这是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();

回答by Zishan

A while back I had been playing around with C2DM to send push notifications. I altered my code as per changes mentioned on this page: http://developer.android.com/guide/google/gcm/c2dm.html#serverto make use for GCM service:

不久前,我一直在玩 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

My SendNotification function:

我的 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

It seems that GCM does not require you to authenticate against Google to obtain an auth key (as the case was with C2DM). Instead, you'll require an API key which is being passed to the SendNotification function. This page should help you get your API key set up: http://developer.android.com/guide/google/gcm/gs.html

似乎 GCM 不要求您对 Google 进行身份验证以获取身份验证密钥(就像 C2DM 的情况一样)。相反,您需要一个传递给 SendNotification 函数的 API 密钥。此页面应该可以帮助您设置 API 密钥:http: //developer.android.com/guide/google/gcm/gs.html

The code for my web form is below just in case:

以防万一,我的网络表单代码如下:

<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>

As for creating your Android app to receiving the push notifications, check out this link: http://developer.android.com/guide/google/gcm/gs.html#android-app

至于创建您的 Android 应用程序以接收推送通知,请查看此链接:http: //developer.android.com/guide/google/gcm/gs.html#android-app

Don't forget to import System.Net, System.IO, System.Security.Cryptography.X509Certificates and System.Net.Security.

不要忘记导入 System.Net、System.IO、System.Security.Cryptography.X509Certificates 和 System.Net.Security。

回答by CularBytes

JSON way

JSON 方式

user1551788 answer works fine, however I like to do it in JSON, which is better practice instead of inserting everything in one line, I think.

user1551788 答案工作正常,但是我喜欢用 JSON 来做,我认为这是更好的做法,而不是在一行中插入所有内容。

The internal class 'jsonObj' is the same as the documentation requires, check the different requests you can make here

内部类 'jsonObj' 与文档要求相同,检查您可以在此处提出的不同请求

A brief description:

简要说明:

to: the phone to send to, insert the registrationId that you received from the phone here. delay_while_idleBy using the delay_while_idle flag, notifications will be delivered once the device becomes active. (out of lock, when the user really uses the phone).

to:要发送到的电话,在此处插入您从电话收到的注册 ID。 delay_while_idle通过使用 delay_while_idle 标志,一旦设备变为活动状态,通知将被传送。(失锁,当用户真正使用手机时)。

data: set datawith custom key/value pairs to pass additional payload to the client app. So, you can put in any variable you want, if you like a json string that contains another object, as long as it does not exceed 4 KB.

datadata使用自定义键/值对设置以将额外的有效负载传递给客户端应用程序。所以,如果你喜欢包含另一个对象的 json 字符串,你可以放入任何你想要的变量,只要它不超过 4 KB。

Some that are also available that I didn't use.

一些我没有使用的也可用。

collapse_key: If set, a notification that has the same collapse_keyname should be overwrite the older notification (metter of good implementation at the phone side when notification is send, on the GCM server it will overwrite when the notification is pending).

collapse_key:如果设置,具有相同collapse_key名称的通知应该覆盖旧的通知(发送通知时在手机端良好实现的指标,在​​ GCM 服务器上,当通知挂起时它将覆盖)。

time_to_live: Straight forward, how long the notification will stay alive, currently not supported for IOS.

time_to_live:直截了当,通知将保持活动状态的时间,目前不支持 IOS。

Some other, see documentation.

其他一些,请参阅文档。

internal class because I didn't need that object outside of my class, which is better for naming like 'data' that could be anything.

内部类,因为我在类之外不需要那个对象,这对于像“数据”这样可以是任何东西的命名更好。

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; }
    }

To use, simply:

要使用,只需:

    //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);

Another great difference I have noticed, the google service returns a json string containing useful information, it tells how many succeeded and how many failed, etc.

我注意到的另一个巨大差异,谷歌服务返回一个包含有用信息的 json 字符串,它告诉有多少成功和多少失败等。

回答by user1528505

Nikunj Ganatra, you can once check out this link for your error type, maybe your application id would be wrong or other details may be incorrect.. http://developer.android.com/guide/google/gcm/gcm.html#top

Nikunj Ganatra,您可以查看此链接以了解您的错误类型,也许您的应用程序 ID 错误或其他详细信息可能不正确.. http://developer.android.com/guide/google/gcm/gcm.html#最佳

Response/Description

200 Message was processed successfully. The response body will contain more details about the message status, but its format will depend whether the request was JSON or plain text. See Interpreting a success response for more details.

400 Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields (for instance, passing a string where a number was expected). The exact failure reason is described in the response and the problem should be addressed before the request can be retried.

401 There was an error authenticating the sender account.

500 There was an internal error in the GCM server while trying to process the request.

503 Indicates that the server is temporarily unavailable (i.e., because of timeouts, etc ). Sender must retry later, honoring any Retry-After header included in the response. Application servers must implement exponential back-off. The GCM server took too long to process the request.

响应/描述

200 消息已成功处理。响应正文将包含有关消息状态的更多详细信息,但其格式将取决于请求是 JSON 还是纯文本。有关更多详细信息,请参阅解释成功响应。

400 仅适用于 JSON 请求。表示请求无法解析为 JSON,或者它包含无效字段(例如,在需要数字的地方传递字符串)。响应中描述了确切的失败原因,并且应该在重试请求之前解决问题。

401 验证发件人帐户时出错。

500 尝试处理请求时 GCM 服务器出现内部错误。

503 表示服务器暂时不可用(即由于超时等)。发送方必须稍后重试,遵守响应中包含的任何 Retry-After 标头。应用服务器必须实现指数退避。GCM 服务器处理请求的时间过长。

I have just rectified it.

我刚刚纠正了它。