support notification queue and worker
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
8645e17060
commit
6efe23923c
|
@ -114,5 +114,6 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
gorush.InitAPNSClient()
|
gorush.InitAPNSClient()
|
||||||
|
gorush.InitWorkers(gorush.PushConf.Core.WorkerNum, gorush.PushConf.Core.QueueNum)
|
||||||
gorush.RunHTTPServer()
|
gorush.RunHTTPServer()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package gorush
|
||||||
import (
|
import (
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfYaml is config structure.
|
// ConfYaml is config structure.
|
||||||
|
@ -18,6 +19,8 @@ type ConfYaml struct {
|
||||||
type SectionCore struct {
|
type SectionCore struct {
|
||||||
Port string `yaml:"port"`
|
Port string `yaml:"port"`
|
||||||
MaxNotification int `yaml:"max_notification"`
|
MaxNotification int `yaml:"max_notification"`
|
||||||
|
WorkerNum int `yaml:"worker_num"`
|
||||||
|
QueueNum int `yaml:"queue_num"`
|
||||||
Mode string `yaml:"mode"`
|
Mode string `yaml:"mode"`
|
||||||
SSL bool `yaml:"ssl"`
|
SSL bool `yaml:"ssl"`
|
||||||
CertPath string `yaml:"cert_path"`
|
CertPath string `yaml:"cert_path"`
|
||||||
|
@ -59,6 +62,8 @@ func BuildDefaultPushConf() ConfYaml {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
conf.Core.Port = "8088"
|
conf.Core.Port = "8088"
|
||||||
|
conf.Core.WorkerNum = runtime.NumCPU()
|
||||||
|
conf.Core.QueueNum = 8192
|
||||||
conf.Core.Mode = "release"
|
conf.Core.Mode = "release"
|
||||||
conf.Core.SSL = false
|
conf.Core.SSL = false
|
||||||
conf.Core.CertPath = "cert.pem"
|
conf.Core.CertPath = "cert.pem"
|
||||||
|
|
|
@ -9,6 +9,8 @@ import (
|
||||||
var (
|
var (
|
||||||
// PushConf is gorush config
|
// PushConf is gorush config
|
||||||
PushConf ConfYaml
|
PushConf ConfYaml
|
||||||
|
// QueueNotification is chan type
|
||||||
|
QueueNotification chan PushNotification
|
||||||
// CertificatePemIos is ios certificate file
|
// CertificatePemIos is ios certificate file
|
||||||
CertificatePemIos tls.Certificate
|
CertificatePemIos tls.Certificate
|
||||||
// ApnsClient is apns client
|
// ApnsClient is apns client
|
||||||
|
|
|
@ -121,8 +121,29 @@ func InitAPNSClient() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendNotification provide send all push request.
|
// InitWorkers for initialize all workers.
|
||||||
func SendNotification(req RequestPush) int {
|
func InitWorkers(workerNum, queueNum int) {
|
||||||
|
LogAccess.Debug("worker number is ", workerNum, ", queue number is ", queueNum)
|
||||||
|
QueueNotification = make(chan PushNotification, queueNum)
|
||||||
|
for i := 0; i < workerNum; i++ {
|
||||||
|
go startWorker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startWorker() {
|
||||||
|
for {
|
||||||
|
notification := <-QueueNotification
|
||||||
|
switch notification.Platform {
|
||||||
|
case PlatFormIos:
|
||||||
|
PushToIOS(notification)
|
||||||
|
case PlatFormAndroid:
|
||||||
|
PushToAndroid(notification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// queueNotification add notification to queue list.
|
||||||
|
func queueNotification(req RequestPush) int {
|
||||||
var count int
|
var count int
|
||||||
for _, notification := range req.Notifications {
|
for _, notification := range req.Notifications {
|
||||||
switch notification.Platform {
|
switch notification.Platform {
|
||||||
|
@ -130,17 +151,14 @@ func SendNotification(req RequestPush) int {
|
||||||
if !PushConf.Ios.Enabled {
|
if !PushConf.Ios.Enabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
count++
|
|
||||||
go PushToIOS(notification)
|
|
||||||
case PlatFormAndroid:
|
case PlatFormAndroid:
|
||||||
if !PushConf.Android.Enabled {
|
if !PushConf.Android.Enabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
count++
|
|
||||||
go PushToAndroid(notification)
|
|
||||||
}
|
}
|
||||||
|
QueueNotification <- notification
|
||||||
|
|
||||||
|
count++
|
||||||
}
|
}
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
@ -242,7 +260,7 @@ func GetIOSNotification(req PushNotification) *apns.Notification {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushToIOS provide send notification to APNs server.
|
// PushToIOS provide send notification to APNs server.
|
||||||
func PushToIOS(req PushNotification) bool {
|
func PushToIOS(req PushNotification) {
|
||||||
|
|
||||||
notification := GetIOSNotification(req)
|
notification := GetIOSNotification(req)
|
||||||
|
|
||||||
|
@ -256,7 +274,7 @@ func PushToIOS(req PushNotification) bool {
|
||||||
// apns server error
|
// apns server error
|
||||||
LogPush(FailedPush, token, req, err)
|
LogPush(FailedPush, token, req, err)
|
||||||
|
|
||||||
return false
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.StatusCode != 200 {
|
if res.StatusCode != 200 {
|
||||||
|
@ -264,15 +282,13 @@ func PushToIOS(req PushNotification) bool {
|
||||||
// ref: https://github.com/sideshow/apns2/blob/master/response.go#L14-L65
|
// ref: https://github.com/sideshow/apns2/blob/master/response.go#L14-L65
|
||||||
LogPush(FailedPush, token, req, errors.New(res.Reason))
|
LogPush(FailedPush, token, req, errors.New(res.Reason))
|
||||||
|
|
||||||
return false
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Sent() {
|
if res.Sent() {
|
||||||
LogPush(SucceededPush, token, req, nil)
|
LogPush(SucceededPush, token, req, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAndroidNotification use for define Android notificaiton.
|
// GetAndroidNotification use for define Android notificaiton.
|
||||||
|
|
|
@ -229,8 +229,8 @@ func TestPushToIOS(t *testing.T) {
|
||||||
Message: "Welcome",
|
Message: "Welcome",
|
||||||
}
|
}
|
||||||
|
|
||||||
success := PushToIOS(req)
|
PushToIOS(req)
|
||||||
assert.False(t, success)
|
// assert.False(t, success)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPushToAndroidWrongAPIKey(t *testing.T) {
|
func TestPushToAndroidWrongAPIKey(t *testing.T) {
|
||||||
|
@ -326,6 +326,8 @@ func TestOverwriteAndroidAPIKey(t *testing.T) {
|
||||||
func TestSenMultipleNotifications(t *testing.T) {
|
func TestSenMultipleNotifications(t *testing.T) {
|
||||||
PushConf = BuildDefaultPushConf()
|
PushConf = BuildDefaultPushConf()
|
||||||
|
|
||||||
|
InitWorkers(2, 2)
|
||||||
|
|
||||||
PushConf.Ios.Enabled = true
|
PushConf.Ios.Enabled = true
|
||||||
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem"
|
||||||
InitAPNSClient()
|
InitAPNSClient()
|
||||||
|
@ -352,7 +354,7 @@ func TestSenMultipleNotifications(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
count := SendNotification(req)
|
count := queueNotification(req)
|
||||||
assert.Equal(t, 2, count)
|
assert.Equal(t, 2, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +387,7 @@ func TestDisabledAndroidNotifications(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
count := SendNotification(req)
|
count := queueNotification(req)
|
||||||
assert.Equal(t, 1, count)
|
assert.Equal(t, 1, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +420,7 @@ func TestDisabledIosNotifications(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
count := SendNotification(req)
|
count := queueNotification(req)
|
||||||
assert.Equal(t, 1, count)
|
assert.Equal(t, 1, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@ func pushHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// process notification.
|
// queue notification.
|
||||||
go SendNotification(form)
|
go queueNotification(form)
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": "ok",
|
"success": "ok",
|
||||||
|
|
Loading…
Reference in New Issue