예제 #1
0
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
		},
	}
}
예제 #2
0
// 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
}