Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
206 views
in Technique[技术] by (71.8m points)

c# - .NET5 send push notification to Apple devices

At the moment I'm programming a REST service in .NET5 for Apple Wallet. All works fine now, registering, unregistering, manual update a card. The problem is the push notification, I know there are a lot of code stuff, how to implement a .NET Apple push notification service, but nothing works for me. I read, I have to use the Pass Type ID certificate and the push token, I get while registering a new wallet card on the Apple device. Here is my code for the push notification stuff

    [HttpGet]
    [Route("passes/{passTypeIdentifier}/{serialNumber}/sendpushnotification")]
    public async Task<IActionResult> SendPushNotificationToAppleAsync(string passTypeIdentifier, string serialNumber)
    {
        var devices = await _context.GetApplePassDevicesAsync(serialNumber, passTypeIdentifier).ConfigureAwait(false);

        if (!devices.Any()) {
            return NotFound();
        }

        try {
            foreach (var device in devices) {
                await SendEmptyApplePushNotificationAsync(device.PushToken).ConfigureAwait(false);
                await _context.SaveApplePushNotificationAsync(device.DeviceLibraryIdentifier, device.PushToken).ConfigureAwait(false);
            }

            return Ok();
        } catch (Exception ex) {
            _logger.LogError($"SendPushNotification error: [{ex.Message}]");
            return NotFound();
        }
    }

    private async Task SendEmptyApplePushNotificationAsync(string pushToken)
    {
        _logger.LogDebug("Trying to send push notification.");

        const string server = "api.sandbox.push.apple.com"; // Develop

        using var tcpClient = new TcpClient(server, 443);
        await using var sslStream = new SslStream(
            tcpClient.GetStream(),
            false,
            ValidateServerCertificate,
            null);

        try {
            var certs = new X509Certificate2Collection();
            X509Certificate cert = await GetAppleServerCertificateAsync().ConfigureAwait(false);
            certs.Add(cert);
            await sslStream.AuthenticateAsClientAsync(server, certs, SslProtocols.Tls12, true).ConfigureAwait(false);
        } catch (AuthenticationException exp) {
            throw new AuthenticationException(exp.Message);
        } catch (IOException exp) {
            throw new IOException(exp.Message);
        }

        var memoryStream = new MemoryStream();
        var writer = new BinaryWriter(memoryStream);
        writer.Write((byte) 0);
        writer.Write((byte) 0);
        writer.Write((byte) 32);
        writer.Write(HexStringToByteArray(pushToken.ToUpper()));

        var payload = new JObject { new JProperty("aps") };
        var json = JsonConvert.SerializeObject(payload);
        writer.Write((byte) 0);
        writer.Write((byte) json.Length);
        var b1 = Encoding.UTF8.GetBytes(json);
        writer.Write(b1);
        writer.Flush();

        var array = memoryStream.ToArray();
        await sslStream.WriteAsync(array.AsMemory()).ConfigureAwait(false);
        await sslStream.FlushAsync().ConfigureAwait(false);
    }

    private static byte[] HexStringToByteArray(string hex)
    {
        return Enumerable.Range(0, hex.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
            .ToArray();
    }

Has anyone a tip for me, what's wrong? I also test port 2197, does not work.

Thank you!

question from:https://stackoverflow.com/questions/66059640/net5-send-push-notification-to-apple-devices

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...