func (self *Client) Connect() error { self.mu.Lock() defer self.mu.Unlock() if self.Connection.State == STATE_CONNECTING || self.Connection.State == STATE_CONNECTED { // 接続中, 試行中なのでなにもしない return nil } connection, err := self.Option.TransporterCallback() if err != nil { return err } if v, ok := connection.(*net.TCPConn); ok { // should enable keepalive. v.SetKeepAlive(true) v.SetNoDelay(true) } self.once = sync.Once{} self.Connection.SetMyConnection(connection) self.wg.Add(1) // send a connect message to MQTT Server msg := codec.NewConnectMessage() msg.Magic = self.Option.Magic msg.Version = uint8(self.Option.Version) msg.Identifier = self.Option.Identifier msg.CleanSession = self.CleanSession msg.KeepAlive = uint16(self.Option.Keepalive) if len(self.Option.WillTopic) > 0 { msg.Will = &codec.WillMessage{ Topic: self.Option.WillTopic, Message: string(self.Option.WillMessage), Retain: self.Option.WillRetain, Qos: uint8(self.Option.WillQos), } } if len(self.Option.UserName) > 0 { msg.UserName = []byte(self.Option.UserName) } if len(self.Option.Password) > 0 { msg.Password = []byte(self.Option.Password) } self.Connection.SetState(STATE_CONNECTING) self.Connection.WriteMessageQueue(msg) self.count += 1 if self.count > 1 { self.reconnect = true } return nil }
func (s *EngineSuite) BenchmarkSimple(c *C) { log.SetupLogging("error", "stdout") engine := CreateEngine() go engine.Run() mock := &MockConnection{} conn := NewMyConnection(nil) conn.SetMyConnection(mock) conn.SetId("debug") hndr := NewHandler(conn, engine) conn.SetOpaque(hndr) msg := codec.NewConnectMessage() msg.Magic = []byte("MQTT") msg.Version = uint8(4) msg.Identifier = "debug" msg.CleanSession = true msg.KeepAlive = uint16(0) // Ping is annoyed at this time codec.WriteMessageTo(msg, mock) // 6) just call conn.ParseMessage(). then handler will work. r, err := conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_CONNECT) // NOTE: Client turn. don't care this. time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_CONNACK) for i := 0; i < c.N; i++ { // (Client) Publish pub := codec.NewPublishMessage() pub.TopicName = "/debug" pub.Payload = []byte("hello") codec.WriteMessageTo(pub, mock) // (Server) conn.ParseMessage() } // That's it. engine.Terminate() }
func (s *EngineSuite) TestBasic(c *C) { log.SetupLogging("error", "stdout") // This test introduce how to setup custom MQTT server // 1) You need to setup Momonga engine like this. engine := CreateEngine() // 2) Running Engine go engine.Run() // 3) engine expects net.Conn (see MockConnection) mock := &MockConnection{} conn := NewMyConnection(nil) conn.SetMyConnection(mock) conn.SetId("debug") // 4) setup handler. This handler implementation is example. // you can customize behaviour with On method. hndr := NewHandler(conn, engine) conn.SetOpaque(hndr) // 5) Now, msg := codec.NewConnectMessage() msg.Magic = []byte("MQTT") msg.Version = uint8(4) msg.Identifier = "debug" msg.CleanSession = true msg.KeepAlive = uint16(0) // Ping is annoyed at this time codec.WriteMessageTo(msg, mock) // 6) just call conn.ParseMessage(). then handler will work. r, err := conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_CONNECT) // NOTE: Client turn. don't care this. time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_CONNACK) // Subscribe sub := codec.NewSubscribeMessage() sub.Payload = append(sub.Payload, codec.SubscribePayload{TopicPath: "/debug"}) sub.PacketIdentifier = 1 codec.WriteMessageTo(sub, mock) // (Server) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_SUBSCRIBE) rsub := r.(*codec.SubscribeMessage) c.Assert(rsub.PacketIdentifier, Equals, uint16(1)) c.Assert(rsub.Payload[0].TopicPath, Equals, "/debug") // (Client) suback time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_SUBACK) // (Client) Publish pub := codec.NewPublishMessage() pub.TopicName = "/debug" pub.Payload = []byte("hello") codec.WriteMessageTo(pub, mock) // (Server) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_PUBLISH) rpub := r.(*codec.PublishMessage) c.Assert(rpub.TopicName, Equals, "/debug") // (Client) received publish message time.Sleep(time.Millisecond) r, err = conn.ParseMessage() rp := r.(*codec.PublishMessage) c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_PUBLISH) c.Assert(rp.TopicName, Equals, "/debug") c.Assert(string(rp.Payload), Equals, "hello") // okay, now disconnect from server dis := codec.NewDisconnectMessage() codec.WriteMessageTo(dis, mock) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) c.Assert(r.GetType(), Equals, codec.PACKET_TYPE_DISCONNECT) // then, receive EOF from server. time.Sleep(time.Millisecond) r, err = conn.ParseMessage() c.Assert(err, Equals, nil) // That's it. engine.Terminate() }