예제 #1
0
func setupLog(ctx *cli.Context) {
	if ctx.Bool("v") {
		logger.SetupLogging("debug", "stderr")
	} else {
		logger.SetupLogging("info", "stderr")
	}
}
예제 #2
0
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()
}
예제 #3
0
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()
}
예제 #4
0
func NewApplication(configPath string) *Application {
	conf, err := configuration.LoadConfiguration(configPath)
	if err != nil {
		log.Error("Can't read config.toml. use default setting.: %s", err)
	}
	log.SetupLogging(conf.Server.LogLevel, conf.Server.LogFile)
	pid := strconv.Itoa(os.Getpid())
	if conf.Server.PidFile != "" {
		if err := ioutil.WriteFile(conf.Server.PidFile, []byte(pid), 0644); err != nil {
			panic(err)
		}
		util.WritePid(conf.Server.PidFile)
	}

	// NOTE: INHERIT=TRUE means the process invoked from os.StartProess
	inherit := false
	if os.Getenv("INHERIT") == "TRUE" {
		inherit = true
	}

	log.Info("Momonga started pid: %s (inherit:%t)", pid, inherit)
	engine := NewMomonga(conf)
	app := &Application{
		Engine:     engine,
		Servers:    []Server{},
		configPath: configPath,
		config:     conf,
	}

	// TODO: improve this block
	if conf.Server.Port > 0 {
		t := NewTcpServer(engine, conf, inherit)
		t.wg = &app.wg
		app.RegisterServer(t)
	}
	if conf.Server.Socket != "" {
		u := NewUnixServer(engine, conf, inherit)
		u.wg = &app.wg
		app.RegisterServer(u)
	}
	if conf.Server.HttpPort > 0 {
		h := NewHttpServer(engine, conf, inherit)
		h.wg = &app.wg
		app.RegisterServer(h)
	}

	if conf.Server.EnableTls && conf.Server.TlsPort > 0 {
		h := NewTlsServer(engine, conf, inherit)
		h.wg = &app.wg
		app.RegisterServer(h)
	}

	// memonized application path
	app.execPath, err = exec.LookPath(os.Args[0])
	if err != nil {
		log.Error("Error: %s", err)
		return app
	}
	app.workingDir, err = os.Getwd()
	if err != nil {
		log.Error("Error: %s", err)
		return app
	}

	if conf.Bridge.Address != "" {
		//TODO: Bridgeは複数指定できる
		//TODO: Bridgeは途中で制御できる
		// /api/bridge/list
		// /api/bridge/connection/stop
		// /api/bridge/connection/status
		// /api/bridge/connection/start
		// /api/bridge/connection/delete
		// /api/bridge/connection/new?address=&port=&type=both&topic[]=
		// /api/bridge/config
		go func() {
			flag := 0
			switch conf.Bridge.Type {
			case "both":
				flag = 3
			case "out":
				flag = 1
			case "in":
				flag = 2
			default:
				panic(fmt.Sprintf("%s does not support.", conf.Bridge.Type))
			}

			// in
			addr := fmt.Sprintf("%s:%d", conf.Bridge.Address, conf.Bridge.Port)
			c := client.NewClient(client.Option{
				TransporterCallback: func() (net.Conn, error) {
					conn, err := net.Dial("tcp", addr)
					return conn, err
				},
				Identifier: fmt.Sprintf(conf.Bridge.ClientId),
				Magic:      []byte("MQTT"),
				Version:    4 | 0x80,
				Keepalive:  0,
			})

			c.Connect()
			c.WaitConnection()
			if flag == 1 || flag == 3 {
				c.Subscribe("#", 2)
				c.SetRequestPerSecondLimit(-1)
				c.On("publish", func(msg *codec.PublishMessage) {
					engine.SendPublishMessage(msg, conf.Bridge.Connection, true)
				})
			}

			//out
			if flag == 2 || flag == 3 {
				addr2 := fmt.Sprintf("%s:%d", conf.Server.BindAddress, conf.Server.Port)
				c2 := client.NewClient(client.Option{
					TransporterCallback: func() (net.Conn, error) {
						conn, err := net.Dial("tcp", addr2)
						return conn, err
					},
					Identifier: fmt.Sprintf(conf.Bridge.ClientId),
					Magic:      []byte("MQTT"),
					Version:    4 | 0x80,
					Keepalive:  0,
				})

				c2.Connect()
				c2.WaitConnection()
				c2.Subscribe("#", 2)
				c2.SetRequestPerSecondLimit(-1)
				c2.On("publish", func(msg *codec.PublishMessage) {
					c.Publish(msg.TopicName, msg.Payload, msg.QosLevel)
				})
			}
			select {}
		}()
	}

	return app
}