func pushNotificationIos(req gaurun.RequestGaurunNotification) bool { var ep string if gaurun.ConfGaurun.Ios.Sandbox { ep = gaurun.EpApnsSandbox } else { ep = gaurun.EpApnsProd } client, err := apns.NewClient( ep, gaurun.ConfGaurun.Ios.PemCertPath, gaurun.ConfGaurun.Ios.PemKeyPath, 0, ) if err != nil { return false } client.TimeoutWaitError = time.Duration(gaurun.ConfGaurun.Ios.TimeoutError) * time.Millisecond for _, token := range req.Tokens { payload := apns.NewPayload() payload.Alert = req.Message payload.Badge = req.Badge payload.Sound = req.Sound pn := apns.NewPushNotification() pn.DeviceToken = token pn.Expiry = uint32(req.Expiry) pn.AddPayload(payload) resp := client.Send(pn) if resp.Error != nil { // reconnect client.Conn.Close() client.ConnTls.Close() client, err = apns.NewClient( ep, gaurun.ConfGaurun.Ios.PemCertPath, gaurun.ConfGaurun.Ios.PemKeyPath, 0, ) if err != nil { return false } client.TimeoutWaitError = time.Duration(gaurun.ConfGaurun.Ios.TimeoutError) * time.Millisecond } } client.Conn.Close() client.ConnTls.Close() 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 } } } }