func NewRedisPool() *redis.Pool { return &redis.Pool{ MaxIdle: config.GetInt("redis_max_idle"), MaxActive: config.GetInt("redis_concurrent"), // max number of connections Dial: func() (redis.Conn, error) { var ( c redis.Conn err error ) redis_host := fmt.Sprintf("%s:%s", config.GetMulti("redis_host", "redis_port")...) redis_passwd := config.Get("redis_passwd") if redis_passwd != "" { pwd := redis.DialPassword(redis_passwd) c, err = redis.Dial("tcp", redis_host, pwd) } else { c, err = redis.Dial("tcp", redis_host) } return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { _, err := c.Do("PING") return err }, } }
// ListenAndServe listents to connections on the URI requested, and handles any // incoming MQTT client sessions. It should not return until Close() is called // or if there's some critical error that stops the server from running. The URI // supplied should be of the form "protocol://host:port" that can be parsed by // url.Parse(). For example, an URI could be "tcp://0.0.0.0:1883". func (this *Server) ListenAndServe() error { defer atomic.CompareAndSwapInt32(&this.running, 1, 0) this.arrayPool = &sync.Pool{ New: func() interface{} { return make([]byte, 50) }, } if !atomic.CompareAndSwapInt32(&this.running, 0, 1) { Log.Error("server/ListenAndServe: Server is already running") return fmt.Errorf("server/ListenAndServe: Server is already running") } this.quit = make(chan struct{}) // _, err := url.Parse(uri) if this.TopicsProvider == "mx" { OnGroupPublish = mxOnGroupPublish //根据pkt_id,将pending队列里的该条消息移除 processAck = mxProcessAck IsOnline = mxIsOnline if config.GetBool("apn_always_reconnect") { onAPNsPush = mxAPNsPush2 } else { onAPNsPush = mxAPNsPush } } else if this.TopicsProvider == "mt" { OnGroupPublish = mtOnGroupPublish processAck = mtProcessAck IsOnline = mtIsOnline onAPNsPush = mtAPNsPush } var err error if strings.Contains(config.Get("uri_scheme"), "ssl") { go func() { cer, err := tls.LoadX509KeyPair(config.Get("ssl_cert"), config.Get("ssl_key")) if err != nil { Log.Error(err) panic(err) } tls_config := &tls.Config{Certificates: []tls.Certificate{cer}} ssl_host := fmt.Sprintf("%s:%s", config.GetMulti("ssl_listen_addr", "ssl_port")...) this.ssl_ln, err = tls.Listen("tcp", ssl_host, tls_config) if err != nil { Log.Error(err) panic(err) } Log.Info("listening ssl: %v", ssl_host) defer this.ssl_ln.Close() var tempDelay time.Duration // how long to sleep on accept failure for { conn, err := this.ssl_ln.Accept() atomic_id := atomic.AddUint64(&gsvcid, 1) Log.Debugc(func() string { var raddr string if conn == nil { raddr = "client but the conn is already Destroyed." } else { raddr = conn.RemoteAddr().String() } return fmt.Sprintf("(%d/_) accepted ssl connection from %s", atomic_id, raddr) }) if err != nil { // Borrowed from go1.3.3/src/pkg/net/http/server.go:1699 if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } Log.Error("(%d/_) server/ListenAndServe: Accept ssl error: %v; retrying in %v", atomic_id, err, tempDelay) time.Sleep(tempDelay) continue } else { Log.Errorc(func() string { return fmt.Sprintf("(%d/_) ssl connection error: %s", atomic_id, err) }) } return } go this.handleConnection(conn, atomic_id) } }() } if strings.Contains(config.Get("uri_scheme"), "tcp") { go func() { tcp_host := fmt.Sprintf("%s:%s", config.GetMulti("tcp_listen_addr", "tcp_port")...) this.ln, err = net.Listen("tcp", tcp_host) if err != nil { Log.Error(err) panic(err) // return } Log.Info("listening tcp: %v", tcp_host) defer this.ln.Close() var tempDelay time.Duration // how long to sleep on accept failure for { conn, err := this.ln.Accept() atomic_id := atomic.AddUint64(&gsvcid, 1) Log.Debugc(func() string { var raddr string if conn == nil { raddr = "client but the conn is already Destroyed." } else { raddr = conn.RemoteAddr().String() } return fmt.Sprintf("(%d/_) accepted tcp connection from %s", atomic_id, raddr) }) if err != nil { // Borrowed from go1.3.3/src/pkg/net/http/server.go:1699 if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } Log.Error("(%d/_) server/ListenAndServe: Accept error: %v; retrying in %v", atomic_id, err, tempDelay) time.Sleep(tempDelay) continue } else { Log.Errorc(func() string { return fmt.Sprintf("(%d/_) tcp connection error: %s", atomic_id, err) }) } return } go this.handleConnection(conn, atomic_id) } }() } if config.GetBool("japn_compatibility") { go func() { tcp_host := "0.0.0.0:2884" this.japn_ln, err = net.Listen("tcp", tcp_host) if err != nil { Log.Error(err) panic(err) // return } Log.Info("listening tcp: %v", tcp_host) defer this.japn_ln.Close() var tempDelay time.Duration // how long to sleep on accept failure for { conn, err := this.japn_ln.Accept() atomic_id := atomic.AddUint64(&gsvcid, 1) Log.Debugc(func() string { var raddr string if conn == nil { raddr = "client but the conn is already Destroyed." } else { raddr = conn.RemoteAddr().String() } return fmt.Sprintf("(%d/_) accepted japn_compatibility connection from %s", atomic_id, raddr) }) if err != nil { // Borrowed from go1.3.3/src/pkg/net/http/server.go:1699 if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } Log.Error("(%d/_) server/ListenAndServe: Accept error: %v; retrying in %v", atomic_id, err, tempDelay) time.Sleep(tempDelay) continue } return } go this.handleConnection(conn, atomic_id) } }() } <-this.quit return nil }