/// <summary> /// 创建 消息体 /// </summary> /// <param name="msg"></param> /// <param name="sBytes"></param> /// <returns></returns> private bool ToBytes(PushMsgModel msg, out byte[] sBytes) { try { var identifier = 0; var identifierBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(identifier)); var expiryTimeStamp = -1;//过期时间戳 if (msg.Expiration != DateTime.MinValue) { DateTime concreteExpireDateUtc = msg.Expiration.ToUniversalTime(); TimeSpan epochTimeSpan = concreteExpireDateUtc - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); expiryTimeStamp = (int)epochTimeSpan.TotalSeconds; } var expiry = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(expiryTimeStamp)); var bytes = new byte[32]; for (var i = 0; i < bytes.Length; i++) { bytes[i] = byte.Parse(msg.DeviceToken.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } if (bytes.Length != DeviceTokenBinarySize) { ApnsResults?.BeginInvoke(-4, "error: Device token length error!", ApnsResultsCallBack, ApnsResults); sBytes = null; return(false); } var deviceTokenSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(bytes.Length))); var str = $"{{\"aps\":{{\"alert\":\"{msg.Alert}\",\"badge\":1,\"sound\":\"default\",\"className\":\"{msg.ClassName}\",\"value\":\"{msg.Values}\",\"storyBoard\":\"{msg.StoryBoard}\",\"version\":\"{msg.Version}\"}}}}"; var payload = Encoding.UTF8.GetBytes(str); var payloadSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt16(payload.Length))); var notificationParts = new List <byte[]> { new byte[] { 0x01 }, identifierBytes, expiry, deviceTokenSize, bytes, payloadSize, payload }; sBytes = BuildBufferFrom(notificationParts); return(true); } catch (Exception) { sBytes = null; return(false); } }
/// <summary> /// 添加需要推送的消息 /// </summary> /// <param name="message">消息体</param> /// <param name="expiration"></param> public void AddMessage(PushMsgModel message, DateTime expiration) { _messageList.Push(message); }
private void SendToApns(PushMsgModel msg) { var tcpClient = new TcpClient(); tcpClient.Connect(HostIp, Port); var sslStream = new SslStream(tcpClient.GetStream(), false, ValidateServerCertificate, SelectLocalCertificate); try { sslStream.AuthenticateAsClient(HostIp, _x509CertificateCollection, System.Security.Authentication.SslProtocols.Tls, false); if (!sslStream.IsMutuallyAuthenticated) { ApnsResults?.BeginInvoke(-1, "error:Ssl Stream Failed to Authenticate!", ApnsResultsCallBack, ApnsResults); return; } if (!sslStream.CanWrite) { ApnsResults?.BeginInvoke(-2, "error:Ssl Stream is not Writable!", ApnsResultsCallBack, ApnsResults); return; } byte[] bytes; var boo = ToBytes(msg, out bytes); if (!boo) { return; } var readBuffer = new byte[6]; var ar = sslStream.BeginRead(readBuffer, 0, 6, asyncResult => { try { sslStream.EndRead(asyncResult); var status = readBuffer[1]; ApnsResults?.BeginInvoke(status, msg.DeviceToken, ApnsResultsCallBack, ApnsResults); } catch { // ignored } }, null); sslStream.Write(bytes); // 发送 if (!ar.IsCompleted) { ar.AsyncWaitHandle.WaitOne(500); if (!ar.IsCompleted) { ApnsResults?.BeginInvoke(-5, msg.DeviceToken, ApnsResultsCallBack, ApnsResults); Disconnect(tcpClient, sslStream); } } } catch (Exception ex) { ApnsResults?.BeginInvoke(-3, $"error: {ex.Message}", ApnsResultsCallBack, ApnsResults); } }