【问题标题】:GCM Push Notification with Asp.Net使用 Asp.Net 的 GCM 推送通知
【发布时间】:2012-06-30 23:32:50
【问题描述】:

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

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

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

【问题讨论】:

    标签: android asp.net push-notification google-cloud-messaging


    【解决方案1】:

    前段时间我一直在玩 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

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

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

    别忘了导入 System.Net、System.IO、System.Security.Cryptography.X509Certificates 和 System.Net.Security。

    【讨论】:

    • 您好紫山,感谢您的回复。您已经发布了使用 C2DM 服务实现的代码。
    • 您好,是否有任何示例或指导线可用于使用 Asp.Net 应用程序实现 Google Cloud Messaging (GCM)?
    • 嗨,Asp.net 中是否有任何可用的解决方案,如:developer.android.com/guide/google/gcm/demo.html
    • 嗨 Nikunj,试试我上面发布的代码。它现在应该可以与 GCM 一起使用了。
    • 紫山,我也按照你的指示实现了代码。但我收到错误消息:远程服务器返回错误:(401)未经授权。在以下行:WebResponse Response = Request.GetResponse();可能是因为请求 url : "android.googleapis.com/gcm/send" *HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("android.googleapis.com/gcm/send"); 请查看我上一个答案/回复的详细信息,因为我的文字有限,所以我不能在此处提供更多详细信息。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      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 服务器处理请求的时间过长。

      我刚刚改正了。

      【讨论】:

        【解决方案4】:

        我有一段代码对我来说运行良好并且可能会有所帮助,我对其进行了测试...

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

        【讨论】:

        • 我尝试了许多可用于发送 GCM 推送的 diff 代码。只有这一个可以完美运行。其他代码正常,但我收到带有空白消息的推送通知。
        • 如何将多个 regid 发送到 GCM?如何发送短信而不是“你收到消息”。
        • 什么是 GoogleAppID?是 API 密钥还是包名?
        • 使用上面的代码,我得到了像 id=0:1374042920524416%5252b7a166d6cf16 这样的服务器响应。我做错了什么吗?我使用 applicationID 作为code.google.com/apis/console 的 API 密钥,senderID 是使用上述链接创建的项目编号。请帮帮我。
        • 对于任何人:applicationID 是 Google API 密钥,senderId 是 google 项目 id,regId 是当您的手机在 GCM 注册时从您的手机收到的 Id。我可以确认它有效,但使用 json 的解决方案会更好,包括多个registrationId。供参考:developers.google.com/cloud-messaging/http
        【解决方案5】:

        JSON 方式

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

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

        简要说明:

        to:要发送到的手机,在此处插入您从手机收到的registrationId。 delay_while_idle 通过使用 delay_while_idle 标志,一旦设备变为活动状态,就会发送通知。 (解锁,当用户真正使用手机时)。

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

        也有一些我没用过的。

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

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

        【讨论】:

          猜你喜欢
          • 2015-03-08
          • 2012-11-27
          • 2016-07-24
          • 2017-06-04
          • 2016-06-19
          • 2016-01-01
          • 2013-02-02
          • 2015-11-30
          • 1970-01-01
          相关资源
          最近更新 更多