C# MemoryStream中的APNS有效负载格式异常
我正试图从C#/dotnetcore发送推送通知,在序列化并将有效负载发送到APN时遇到了问题 如果您查看下面的代码示例,那么iosPayload对象有一个注释掉的属性。如果有效负载中没有它,则会成功接收通知,有了它,通知不会到达设备C# MemoryStream中的APNS有效负载格式异常,c#,.net,.net-core,apple-push-notifications,C#,.net,.net Core,Apple Push Notifications,我正试图从C#/dotnetcore发送推送通知,在序列化并将有效负载发送到APN时遇到了问题 如果您查看下面的代码示例,那么iosPayload对象有一个注释掉的属性。如果有效负载中没有它,则会成功接收通知,有了它,通知不会到达设备 public void SendNotification(string deviceToken) { int port = 2195; string hostname = "gateway.sandbox.push.apple.com";
public void SendNotification(string deviceToken)
{
int port = 2195;
string hostname = "gateway.sandbox.push.apple.com";
var iosPayload = new {
aps = new {
alert = "The title",
sound = "default"
},
app_group_id = 1,
notification_id = "notification_id",
campaignName = "Campaign Name",
push_title = "Campaign Title",
push_message = "The main body",
type = "sdkNotification",
push_on_click_behaviour = "1"//,
//another_property = "4"
};
string certificatePath = @"./com.myCompany.sampleIOS.DEV.p12";
X509Certificate2 clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "");
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
TcpClient tcpClient = new TcpClient(hostname, port);
SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(deviceToken.ToUpper()));
var payload = JsonConvert.SerializeObject(iosPayload);
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(payloadBytes);
writer.Flush();
byte[] memoryStreamAsBytes = memoryStream.ToArray();
sslStream.Write(memoryStreamAsBytes);
sslStream.Flush();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
tcpClient.Close();
}
}
private byte[] HexStringToByteArray(string hexString)
{
return Enumerable.Range(0, hexString.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
.ToArray();
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None) return true;
return false;
}
错误为System.FormatException
,消息为,字符串末尾有其他不可解析字符。实际上,我是从Azure Webjob中发送的,只有在那里我才会收到错误消息,在本地运行的简单控制台应用程序不会显示任何错误,但也不会到达设备
public void SendNotification(string deviceToken)
{
int port = 2195;
string hostname = "gateway.sandbox.push.apple.com";
var iosPayload = new {
aps = new {
alert = "The title",
sound = "default"
},
app_group_id = 1,
notification_id = "notification_id",
campaignName = "Campaign Name",
push_title = "Campaign Title",
push_message = "The main body",
type = "sdkNotification",
push_on_click_behaviour = "1"//,
//another_property = "4"
};
string certificatePath = @"./com.myCompany.sampleIOS.DEV.p12";
X509Certificate2 clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "");
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
TcpClient tcpClient = new TcpClient(hostname, port);
SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(deviceToken.ToUpper()));
var payload = JsonConvert.SerializeObject(iosPayload);
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(payloadBytes);
writer.Flush();
byte[] memoryStreamAsBytes = memoryStream.ToArray();
sslStream.Write(memoryStreamAsBytes);
sslStream.Flush();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
tcpClient.Close();
}
}
private byte[] HexStringToByteArray(string hexString)
{
return Enumerable.Range(0, hexString.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
.ToArray();
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None) return true;
return false;
}
编辑:奇怪的是,我可以从Pusher发送我的全部有效载荷…结果是,我调用的是由序列的第一个字节决定命令的。我将0作为命令发送,该API的最大有效负载大小为256字节。很明显,我的有效载荷比这个稍大,所以被拒绝了
然后我发送了2作为命令,并建立了必要的帧数据