func pushNotificationIos(req RequestGaurunNotification, client *apns.Client) bool { LogError.Debug("START push notification for iOS") for i, token := range req.Tokens { id := req.IDs[i] payload := apns.NewPayload() payload.Alert = req.Message payload.Badge = req.Badge payload.Sound = req.Sound payload.ContentAvailable = req.ContentAvailable pn := apns.NewPushNotification() pn.DeviceToken = token pn.Expiry = uint32(req.Expiry) pn.AddPayload(payload) if len(req.Extend) > 0 { for _, extend := range req.Extend { pn.Set(extend.Key, extend.Value) } } stime := time.Now() resp := client.Send(pn) etime := time.Now() ptime := etime.Sub(stime).Seconds() if resp.Error != nil { atomic.AddInt64(&StatGaurun.Ios.PushError, 1) LogPush(req.IDs[i], StatusFailedPush, token, ptime, req, resp.Error) client.Conn.Close() client.ConnTls.Close() return false } else { LogPush(id, StatusSucceededPush, token, ptime, req, nil) atomic.AddInt64(&StatGaurun.Ios.PushSuccess, 1) } } client = nil LogError.Debug("END push notification for iOS") return true }
func pushNotificationWorker() { var ( success bool retryMax int ep string apnsClient *apns.Client loop int err error ) if ConfGaurun.Ios.Sandbox { ep = EpApnsSandbox } else { ep = EpApnsProd } apnsClient = nil loop = 0 for { stime := time.Now() notification := <-QueueNotification etime := time.Now() itime := etime.Sub(stime).Seconds() if notification.Platform == PlatFormIos { if apnsClient != nil && int(itime) > ConfGaurun.Ios.KeepAliveIdleTimeout { apnsClient.Conn.Close() apnsClient.ConnTls.Close() apnsClient = nil } if apnsClient != nil && ConfGaurun.Ios.KeepAliveMax > 0 && loop > ConfGaurun.Ios.KeepAliveMax { apnsClient.Conn.Close() apnsClient.ConnTls.Close() apnsClient = nil loop = 0 } loop++ if apnsClient == nil { apnsClient, err = apns.NewClient( ep, ConfGaurun.Ios.PemCertPath, ConfGaurun.Ios.PemKeyPath, 0, ) if err != nil { LogError.Errorf("failed to connect to APNS: %s", err.Error()) apnsClient = nil loop = 0 QueueNotification <- notification continue } apnsClient.TimeoutWaitError = time.Duration(ConfGaurun.Ios.TimeoutError) * time.Millisecond } } switch notification.Platform { case PlatFormIos: success = pushNotificationIos(notification, apnsClient) if !success { apnsClient = nil } retryMax = ConfGaurun.Ios.RetryMax case PlatFormAndroid: success = pushNotificationAndroid(notification) retryMax = ConfGaurun.Android.RetryMax } if !success && notification.Retry < retryMax { if len(QueueNotification) < cap(QueueNotification) { notification.Retry++ QueueNotification <- notification } } } }