c# 中的 Apple 推送通知服务代码服务器端
Apple Push Notification Service code server side in c#
查看下面的编辑,我发现问题出在 c# 代码上,但无法找到位置!
我知道以前的最大负载大小是 256b,但现在 ios8 我们可以发送最多 2kb 的负载,但这对我不起作用。
这里声明:
APN (Apple Push Notification) payload size limit
示例:
如果我发送此有效载荷工作正常(我收到通知):
{"aps":{"alert":"New negotiation opened from (idOperation: 5) pablo.gomez","sound":"default"},"data":{"notificationType":"2","idOperation":"5","link":"http://localhost:7000/Login.aspx?idInstance=9&forward=VE9fVHJhZGluZy5hc3B4P2lkT3BlcmF0aW9uPTU="}}
但是,如果我发送的时间更长,它将无法正常工作(我没有在 phone 上收到它),例如:
"{"aps":{"alert":"New negotiation test test test test test test test opened from (idOperation: 5) pablo.gomez","sound":"default"},"data":{"notificationType":"2","idOperation":"5","link":"http://localhost:7000/Login.aspx?idInstance=9&forward=VE9fVHJhZGluZy5hc3B4P2lkT3BlcmF0aW9uPTU="}}"
我也在开发和生产中尝试过这个。第二个都失败了。我用 iPhone 5 iOS 8.1.3
测试过这个
我的应用程序有 iOS 部署目标 iOS 8.0 但我上传到商店的版本有部署目标 iOS 7.0,所以这可能是我测试时的问题有生产环境?
我在这里阅读了一些关于通知类别的内容:
iOS8 and iOS7 Push Notification Payload
也许这可以解决问题?
这就是我使用 c#
将负载发送到苹果的方式
...
try
{
memoryStream = new MemoryStream();
writer = new BinaryWriter(memoryStream);
writer.Write((byte)0); //The command
writer.Write((byte)0); //The first byte of the deviceId length (big-endian first byte)
writer.Write((byte)32); //The deviceId length (big-endian second byte)
//bw.Write(new byte[] { 0, 0, 32 }); Other way of doing this.
writer.Write(this.HexStringToByteArray(token.ToUpper()));
writer.Write((byte)0);
writer.Write((byte)payload.Length);
writer.Write(System.Text.Encoding.UTF8.GetBytes(payload));
writer.Flush();
sslStream.Write(memoryStream.ToArray());
sslStream.Flush();
responseString += " SENT TO: " + token + "<br />";
}
...
private byte[] HexStringToByteArray(string hexString)
{
if (hexString == null)
return null;
if (hexString.Length % 2 == 1)
hexString = '0' + hexString; // Up to you whether to pad the first or last byte
byte[] data = new byte[hexString.Length / 2];
for (int i = 0; i < data.Length; i++)
data[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return data;
}
编辑:我尝试使用 PHP 中的脚本推送 notif 工作正常所以问题是为什么我的 c# 代码..但在这里找不到问题..
好的,终于弄清楚问题出在哪里了。
正如您在代码中看到的那样,我正在发送命令 0
,这是通知服务的旧版本。
所以我进行了重构以支持这个新版本,现在所有通知都可以正常接收。
工作代码是这样的:
...
try
{
memoryStream = new MemoryStream();
writer = new BinaryWriter(memoryStream);
writer.Write((byte)2); // The command (version 2)
// 4 bytes for the frameLength (this includes all the items ids listed below)
int frameLength = 1 + 2 + 32 + 1 + 2 + payload.Length; // (tokenCommand + tokenLength + token) + (payloadCommand + payloadLength + payload)
this.writeIntBytesAsBigEndian(writer, frameLength, 4);
// DEVICE ID
writer.Write((byte)1); // Command for Item ID: deviceId
byte[] tokenBytes = this.HexStringToByteArray(token);
this.writeIntBytesAsBigEndian(writer, tokenBytes.Length, 2);
writer.Write(tokenBytes);
// PAYLOAD
writer.Write((byte)2); // Command for Item ID: payload
this.writeIntBytesAsBigEndian(writer, payload.Length, 2);
writer.Write(Encoding.ASCII.GetBytes(payload), 0, payload.Length);
writer.Flush();
sslStream.Write(memoryStream.ToArray());
sslStream.Flush();
responseString += " SENT TO: " + token + "<br />";
}
...
private void writeIntBytesAsBigEndian(BinaryWriter writer, int value, int bytesCount)
{
byte[] bytes = null;
if (bytesCount == 2)
bytes = BitConverter.GetBytes((Int16)value);
else if (bytesCount == 4)
bytes = BitConverter.GetBytes((Int32)value);
else if (bytesCount == 8)
bytes = BitConverter.GetBytes((Int64)value);
if (bytes != null)
{
Array.Reverse(bytes);
writer.Write(bytes, 0, bytesCount);
}
}
查看下面的编辑,我发现问题出在 c# 代码上,但无法找到位置!
我知道以前的最大负载大小是 256b,但现在 ios8 我们可以发送最多 2kb 的负载,但这对我不起作用。
这里声明: APN (Apple Push Notification) payload size limit
示例:
如果我发送此有效载荷工作正常(我收到通知):
{"aps":{"alert":"New negotiation opened from (idOperation: 5) pablo.gomez","sound":"default"},"data":{"notificationType":"2","idOperation":"5","link":"http://localhost:7000/Login.aspx?idInstance=9&forward=VE9fVHJhZGluZy5hc3B4P2lkT3BlcmF0aW9uPTU="}}
但是,如果我发送的时间更长,它将无法正常工作(我没有在 phone 上收到它),例如:
"{"aps":{"alert":"New negotiation test test test test test test test opened from (idOperation: 5) pablo.gomez","sound":"default"},"data":{"notificationType":"2","idOperation":"5","link":"http://localhost:7000/Login.aspx?idInstance=9&forward=VE9fVHJhZGluZy5hc3B4P2lkT3BlcmF0aW9uPTU="}}"
我也在开发和生产中尝试过这个。第二个都失败了。我用 iPhone 5 iOS 8.1.3
测试过这个我的应用程序有 iOS 部署目标 iOS 8.0 但我上传到商店的版本有部署目标 iOS 7.0,所以这可能是我测试时的问题有生产环境?
我在这里阅读了一些关于通知类别的内容: iOS8 and iOS7 Push Notification Payload
也许这可以解决问题?
这就是我使用 c#
将负载发送到苹果的方式 ...
try
{
memoryStream = new MemoryStream();
writer = new BinaryWriter(memoryStream);
writer.Write((byte)0); //The command
writer.Write((byte)0); //The first byte of the deviceId length (big-endian first byte)
writer.Write((byte)32); //The deviceId length (big-endian second byte)
//bw.Write(new byte[] { 0, 0, 32 }); Other way of doing this.
writer.Write(this.HexStringToByteArray(token.ToUpper()));
writer.Write((byte)0);
writer.Write((byte)payload.Length);
writer.Write(System.Text.Encoding.UTF8.GetBytes(payload));
writer.Flush();
sslStream.Write(memoryStream.ToArray());
sslStream.Flush();
responseString += " SENT TO: " + token + "<br />";
}
...
private byte[] HexStringToByteArray(string hexString)
{
if (hexString == null)
return null;
if (hexString.Length % 2 == 1)
hexString = '0' + hexString; // Up to you whether to pad the first or last byte
byte[] data = new byte[hexString.Length / 2];
for (int i = 0; i < data.Length; i++)
data[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return data;
}
编辑:我尝试使用 PHP 中的脚本推送 notif 工作正常所以问题是为什么我的 c# 代码..但在这里找不到问题..
好的,终于弄清楚问题出在哪里了。
正如您在代码中看到的那样,我正在发送命令 0
,这是通知服务的旧版本。
所以我进行了重构以支持这个新版本,现在所有通知都可以正常接收。
工作代码是这样的:
...
try
{
memoryStream = new MemoryStream();
writer = new BinaryWriter(memoryStream);
writer.Write((byte)2); // The command (version 2)
// 4 bytes for the frameLength (this includes all the items ids listed below)
int frameLength = 1 + 2 + 32 + 1 + 2 + payload.Length; // (tokenCommand + tokenLength + token) + (payloadCommand + payloadLength + payload)
this.writeIntBytesAsBigEndian(writer, frameLength, 4);
// DEVICE ID
writer.Write((byte)1); // Command for Item ID: deviceId
byte[] tokenBytes = this.HexStringToByteArray(token);
this.writeIntBytesAsBigEndian(writer, tokenBytes.Length, 2);
writer.Write(tokenBytes);
// PAYLOAD
writer.Write((byte)2); // Command for Item ID: payload
this.writeIntBytesAsBigEndian(writer, payload.Length, 2);
writer.Write(Encoding.ASCII.GetBytes(payload), 0, payload.Length);
writer.Flush();
sslStream.Write(memoryStream.ToArray());
sslStream.Flush();
responseString += " SENT TO: " + token + "<br />";
}
...
private void writeIntBytesAsBigEndian(BinaryWriter writer, int value, int bytesCount)
{
byte[] bytes = null;
if (bytesCount == 2)
bytes = BitConverter.GetBytes((Int16)value);
else if (bytesCount == 4)
bytes = BitConverter.GetBytes((Int32)value);
else if (bytesCount == 8)
bytes = BitConverter.GetBytes((Int64)value);
if (bytes != null)
{
Array.Reverse(bytes);
writer.Write(bytes, 0, bytesCount);
}
}