func startServiceN(t testing.TB, u *url.URL, wg *sync.WaitGroup, ready1, ready2 chan struct{}, cnt int) { defer wg.Done() topics.Unregister("mem") tp := topics.NewMemProvider() topics.Register("mem", tp) sessions.Unregister("mem") sp := sessions.NewMemProvider() sessions.Register("mem", sp) ln, err := net.Listen(u.Scheme, u.Host) require.NoError(t, err) defer ln.Close() close(ready1) svr := &Server{ Authenticator: authenticator, } for i := 0; i < cnt; i++ { conn, err := ln.Accept() require.NoError(t, err) _, err = svr.handleConnection(conn) if authenticator == "mockFailure" { require.Error(t, err) return } else { require.NoError(t, err) } } <-ready2 for _, svc := range svr.svcs { glog.Infof("Stopping service %d", svc.id) svc.stop() } }
// Connect is for MQTT clients to open a connection to a remote server. It needs to // know the URI, e.g., "tcp://127.0.0.1:1883", so it knows where to connect to. It also // needs to be supplied with the MQTT CONNECT message. func (this *Client) Connect(uri string, msg *message.ConnectMessage) (err error) { this.checkConfiguration() if msg == nil { return fmt.Errorf("msg is nil") } u, err := url.Parse(uri) if err != nil { return err } if u.Scheme != "tcp" { return ErrInvalidConnectionType } conn, err := net.Dial(u.Scheme, u.Host) if err != nil { return err } defer func() { if err != nil { conn.Close() } }() if msg.KeepAlive() < minKeepAlive { msg.SetKeepAlive(minKeepAlive) } if err = writeMessage(conn, msg); err != nil { return err } conn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(this.ConnectTimeout))) resp, err := getConnackMessage(conn) if err != nil { return err } if resp.ReturnCode() != message.ConnectionAccepted { return resp.ReturnCode() } this.svc = &service{ id: atomic.AddUint64(&gsvcid, 1), client: true, conn: conn, keepAlive: int(msg.KeepAlive()), connectTimeout: this.ConnectTimeout, ackTimeout: this.AckTimeout, timeoutRetries: this.TimeoutRetries, } err = this.getSession(this.svc, msg, resp) if err != nil { return err } p := topics.NewMemProvider() topics.Register(this.svc.sess.ID(), p) this.svc.topicsMgr, err = topics.NewManager(this.svc.sess.ID()) if err != nil { return err } if err := this.svc.start(); err != nil { this.svc.stop() return err } this.svc.inStat.increment(int64(msg.Len())) this.svc.outStat.increment(int64(resp.Len())) return nil }