Пример #1
0
//---------------------------------------------------------- Hub processing
func HubAgent(incoming chan []byte, conn net.Conn) {
	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	hostid := atomic.AddInt32(&_host_genid, 1)
	// forward buffer
	forward := make(chan []byte, MAXCHAN)
	// output buffer
	output := make(chan []byte, MAXCHAN)

	protos.AddServer(hostid, forward)
	log.Printf("game server [id:%v] connected\n", hostid)

	go _write_routine(output, conn)

	defer func() {
		protos.RemoveServer(hostid)
		core.LogoutServer(hostid)
		close(forward)
		close(output)

		log.Printf("game server [id:%v] disconnected\n", hostid)
	}()

	for {
		select {
		case msg, ok := <-incoming: // from hub
			if !ok {
				return
			}

			reader := packet.Reader(msg)
			protos.HandleRequest(hostid, reader, output)
		case msg := <-forward: // send forward packet
			helper.SendChan(0, msg, output)
		}
	}

}
Пример #2
0
//---------------------------------------------------------- Event Server start
func EventStart() {
	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	// start logger
	if config["event_log"] != "" {
		cfg.StartLogger(config["event_log"])
	}

	log.Println("Starting Event Server")
	startup_work()
	go SignalProc()

	// Listen
	service := DEFAULT_SERVICE
	if config["event_service"] != "" {
		service = config["event_service"]
	}

	log.Println("Event Service:", service)
	tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	log.Println("Event Server OK.")
	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			continue
		}
		helper.SetConnParam(conn)
		go handleClient(conn)
	}
}
Пример #3
0
//----------------------------------------------- Start Agent when a client is connected
func StartAgent(in chan []byte, conn net.Conn) {
	defer helper.PrintPanicStack()

	config := cfg.Get()
	if config["profile"] == "true" {
		helper.SetMemProfileRate(1)
		defer func() {
			helper.GC()
			helper.DumpHeap()
			helper.PrintGCSummary()
		}()
	}

	var sess Session
	sess.IP = net.ParseIP(conn.RemoteAddr().String())
	sess.MQ = make(chan IPCObject, DEFAULT_MQ_SIZE)
	sess.ConnectTime = time.Now()
	sess.LastPacketTime = time.Now().Unix()
	sess.KickOut = false

	// standard 1-sec timer
	std_timer := make(chan int32, 1)
	timer.Add(1, time.Now().Unix()+1, std_timer)

	// write buffer
	bufctrl := make(chan bool)
	buf := NewBuffer(&sess, conn, bufctrl)
	go buf.Start()

	// max # of operartions allowed before flushing
	flush_ops, err := strconv.Atoi(config["flush_ops"])
	if err != nil {
		log.Println("cannot parse flush_ops from config", err)
		flush_ops = DEFAULT_FLUSH_OPS
	}

	// cleanup work
	defer func() {
		close_work(&sess)
		close(bufctrl)
	}()

	// the main message loop
	for {
		select {
		case msg, ok := <-in:
			if !ok {
				return
			}

			if result := UserRequestProxy(&sess, msg); result != nil {
				err := buf.Send(result)
				if err != nil {
					return
				}
			}
			sess.LastPacketTime = time.Now().Unix()

		case msg, ok := <-sess.MQ: // async
			if !ok {
				return
			}

			if result := IPCRequestProxy(&sess, &msg); result != nil {
				err := buf.Send(result)
				if err != nil {
					return
				}
			}

		case <-std_timer:
			timer_work(&sess)
			if session_timeout(&sess) {
				return
			}
			timer.Add(1, time.Now().Unix()+1, std_timer)
		}

		// 持久化逻辑#1: 超过一定的操作数量,刷入数据库
		if sess.OpCount > flush_ops {
			_flush(&sess)
		}

		// 是否被逻辑踢出
		if sess.KickOut {
			return
		}
	}
}