//------------------------------------------------ Game Server Request Proxy func GSProxy(hostid int32, reader *packet.Packet) (ret []byte) { defer helper.PrintPanicStack() // read protocol number b, err := reader.ReadS16() if err != nil { log.Println("read protocol error") return } // get handler handle := protos.ProtoHandler[b] if handle == nil { log.Println("service not bind", b) return } // call handler start := time.Now() ret = handle(hostid, reader) end := time.Now() log.Printf("code: %v %v TIME:%v\n", b, protos.RCode[b], end.Sub(start)) return ret }
//----------------------------------------------- Start Agent when a client is connected func StartAgent(sess *Session, in chan []byte, out *Buffer) { wg.Add(1) defer wg.Done() defer helper.PrintPanicStack() // init session sess.MQ = make(chan IPCObject, DEFAULT_MQ_SIZE) sess.ConnectTime = time.Now() sess.LastPacketTime = time.Now() // custom-sec timer, 60-sec custom_timer := make(chan int32, 1) timer.Add(-1, time.Now().Unix()+CUSTOM_TIMER, custom_timer) // cleanup work defer func() { close_work(sess) }() // the main message loop for { select { case msg, ok := <-in: // network protocol if !ok { return } sess.PacketTime = time.Now() if result := UserRequestProxy(sess, msg); result != nil { err := out.Send(result) if err != nil { helper.ERR("cannot send to client", err) return } } sess.LastPacketTime = sess.PacketTime sess.PacketCount++ // packet count case msg := <-sess.MQ: // internal IPC if result := IPCRequestProxy(sess, &msg); result != nil { err := out.Send(result) if err != nil { helper.ERR("cannot send ipc response", err) return } } case <-custom_timer: // 60-sec timer timer_work(sess) timer.Add(-1, time.Now().Unix()+CUSTOM_TIMER, custom_timer) case <-die: sess.Flag |= SESS_KICKED_OUT } // is the session been kicked out if sess.Flag&SESS_KICKED_OUT != 0 { return } } }
func HandleRequest(hostid int32, reader *packet.Packet, output chan []byte) { defer helper.PrintPanicStack() seqid, err := reader.ReadU64() // read seqid if err != nil { log.Println("Read Sequence Id failed.", err) return } b, err := reader.ReadS16() if err != nil { log.Println("read protocol error") return } handle := ProtoHandler[b] if handle != nil { ret := handle(hostid, reader) if len(ret) != 0 { helper.SendChan(seqid, ret, output) } } }
//----------------------------------------------- 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 } } }