func (a *Account) work(id int) { log.LogMessage("db work, id:", id) var start_time time.Time var delay time.Duration warninglvl := 50 * time.Millisecond for { select { case caller := <-a.queue[id]: log.LogMessage(caller.GetSrc(), " rpc call:", caller.GetMethod(), ", thread:", id) start_time = time.Now() err := caller.Call() if err != nil { log.LogError("rpc error:", err) } delay = time.Now().Sub(start_time) if delay > warninglvl { log.LogWarning("rpc call ", caller.GetMethod(), " delay:", delay.Nanoseconds()/1000000, "ms") } caller.Free() break default: if a.quit { return } time.Sleep(time.Millisecond) } } }
//callback func (gd *GlobalDataHelper) OnCreateGlobalData(msg *rpc.Message) { var appname string if err := ParseArgs(msg, &appname); err != nil { log.LogError(err) return } ret := GetReplyError(msg) client, exist := gd.globalclients[appname] if !exist { return } if ret == share.ERR_FUNC_BEGIN+1 { client.disable = false log.LogMessage(appname, " global data is disabled") return } if ret != share.ERR_REPLY_SUCCEED { client.errcount++ client.status = STATUS_NONE return } client.status = STATUS_CREATED log.LogMessage("create global data to ", appname, " succeed") }
//处理由客户端的发起远程调用 func (app *RemoteApp) Handle(src rpc.Mailbox, method string, args interface{}) error { app.Lock() defer app.Unlock() if app.Id == core.AppId { log.LogMessage("rpc inner handle:", method) return core.rpcServer.Call("C2S"+method, src, args) } if app.Conn == nil { if app.Conn == nil { conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", app.Host, app.Port), time.Second) if err != nil { return err } app.Conn = conn app.RpcClient = rpc.NewClient(conn) log.LogMessage("rpc connected:", app.Name, ",", fmt.Sprintf("%s:%d", app.Host, app.Port)) } } log.LogMessage("remote handle:", app.Name, "/", method) err := app.RpcClient.Call("C2S"+method, src, args) if err == rpc.ErrShutdown { log.LogError(err) app.Close() } return err }
func (t *Thread) work(id int) { log.LogMessage(t.TAG, " thread work, id:", id) var start_time time.Time var delay time.Duration warninglvl := 50 * time.Millisecond for { select { case rpc := <-t.Queue[id]: log.LogMessage(t.TAG, " thread:", id, rpc.GetSrc(), " call:", rpc.GetMethod()) start_time = time.Now() err := rpc.Call() if err != nil { log.LogError("rpc error:", err) } delay = time.Now().Sub(start_time) if delay > warninglvl { log.LogWarning("rpc call ", rpc.GetMethod(), " delay:", delay.Nanoseconds()/1000000, "ms") } err = rpc.Done() if err != nil { log.LogError("rpc error:", err) } rpc.Free() break default: if t.Quit { log.LogMessage(t.TAG, " thread ", id, " quit") return } time.Sleep(time.Millisecond) } } }
func (c *Coroutines) Run(job func(interface{}, interface{}) int, args interface{}, reply interface{}) { log.LogMessage("coroutine ", c.workid, " is started") ret := job(args, reply) c.result = ret c.reply = reply coroutinecomplete <- c.workid log.LogMessage("coroutine ", c.workid, " is complete") }
func (a *Areas) GetArea(mailbox rpc.Mailbox, id string) error { a.l.Lock() defer a.l.Unlock() log.LogMessage("GetArea") app := server.GetAppByName(mailbox.App) if app == nil { return server.ErrAppNotFound } if areainfo, exist := a.areas[id]; exist { if areainfo.Status == AREA_CREATED { return app.Call(&mailbox, "AreaBridge.GetAreaBak", areainfo.AppId) } else { a.pending[id].PushBack(mailbox) return nil } } a.lastareaid++ appid := fmt.Sprintf("area_%d", a.lastareaid) data, err := share.CreateAppMsg("area", id, appid, fmt.Sprintf(`{ "id":"%s", "host":"127.0.0.1", "port":0, "areaid":"%s"}`, appid, id), App.Name, ) if err != nil { log.LogError(err) return app.Call(&mailbox, "AreaBridge.GetAreaBak", "") } err = App.SendToMaster(data) if err != nil { log.LogError(err) return app.Call(&mailbox, "AreaBridge.GetAreaBak", "") } ar := &area{} ar.AppId = appid ar.Status = AREA_CREATING a.areas[id] = ar l := list.New() l.PushBack(mailbox) a.pending[id] = l log.LogMessage(a) return nil }
func (pl *PlayerList) UpdatePlayer(mailbox rpc.Mailbox, msg *rpc.Message) (errcode int32, reply *rpc.Message) { r := server.NewMessageReader(msg) account, err := r.ReadString() if server.Check(err) { return 0, nil } role_name, err := r.ReadString() if server.Check(err) { return 0, nil } base_id, err := r.ReadString() if server.Check(err) { return 0, nil } if base_id == "" { if acc, ok := pl.accounts[account]; ok { pl := acc.GetPlayInfo(role_name) if pl != nil { delete(acc.roles, account) log.LogMessage("remove ", account, ",", role_name) } } return 0, nil } if acc, ok := pl.accounts[account]; ok { p := acc.GetPlayInfo(role_name) if p != nil { log.LogMessage("update ", account, ",", role_name, " base:", base_id) p.BaseId = base_id return 0, nil } p = &PlayerInfo{role_name, base_id} acc.roles[role_name] = p log.LogMessage("add ", account, ",", role_name, " base:", base_id) return 0, nil } p := &PlayerInfo{role_name, base_id} acc := &AccountInfo{} acc.roles = make(map[string]*PlayerInfo, MAX_ROLES) acc.roles[role_name] = p pl.accounts[account] = acc log.LogMessage("add ", account, ",", role_name, " base:", base_id) return 0, nil }
//注册函数 func Register(name string, createfunc func() Entityer) { if _, dup := objects[name]; dup { panic("entity: Register called twice for object " + name) } log.LogMessage("register entity:", name) objects[name] = createfunc }
//数据库加载回调 func (gd *GlobalDataHelper) OnLoadGlobalData(msg *rpc.Message) { ret := GetReplyError(msg) if ret == share.ERR_REPLY_FAILED { log.LogError("global data is empty") if err := gd.createDataSet(); err != nil { log.LogError("create global data error:", err) } return } if ret != share.ERR_REPLY_SUCCEED { log.LogError("global data load error, errcode:", ret) return } var callbackparams share.DBParams var savedata share.DbSave if err := ParseArgs(msg, &callbackparams, &savedata); err != nil { log.LogError("load global data error:", err) return } ent, err := core.CreateFromDb(&savedata) if err != nil { log.LogError("create global data set failed, err:", err) } if gd.dataset != nil { core.Destroy(gd.dataset.GetObjId()) } gd.dataset = ent gd.ready = true gd.OnDataReady() log.LogMessage("load global succeed") }
func (a *Areas) createAppBak(bak share.CreateAppBak) { a.l.Lock() defer a.l.Unlock() appid := "" if bak.Res == "ok" { a.areas[bak.Id].Status = AREA_CREATED appid = bak.AppId } else { delete(a.areas, bak.Id) } log.LogMessage(bak, a) p := a.pending[bak.Id] var next *list.Element for e := p.Front(); e != nil; e = next { next = e.Next() mailbox := e.Value.(rpc.Mailbox) p.Remove(e) app := server.GetAppByName(mailbox.App) if app == nil { continue } app.Call(&mailbox, "AreaBridge.GetAreaBak", appid) } delete(a.pending, bak.Id) }
func (c *Client) Start() { log.LogMessage("client start:", c.id) conn, err := net.Dial("tcp", "172.30.9.101:5391") if err != nil { log.LogError(err) return } c.buf = make([]byte, 1024*16) mid, data, err := util.ReadPkg(conn, c.buf) if err != nil { log.LogError(err) log.LogError("quit client ", c.id) return } l := &s2c.Login{} err = ParseProto(mid, data, l) if err != nil { log.LogError(err) log.LogError("quit client ", c.id) return } conn.Close() c.Login(l.GetHost(), l.GetPort()) }
func (this *cell) AddObject(obj Entityer) error { id := obj.GetObjId() if _, ok := this.Objects[obj.ObjType()]; !ok { this.Objects[obj.ObjType()] = make(map[int32]Entityer, 256) } if _, dup := this.Objects[obj.ObjType()][id.Index]; dup { return errors.New("object already added") } this.Objects[obj.ObjType()][id.Index] = obj if obj.ObjType() == PLAYER { App.EntryScene(obj) this.enterScene(obj) App.baseProxy.entryScene(this.scene, obj) App.EnterScene(obj) log.LogMessage("add player:", obj.GetObjId()) this.playernum++ this.livetime = -1 } else { this.enterScene(obj) } return nil }
func Start(startapp string, name string, appuid int32, typ string, startargs string) error { ferr, err := os.Create(fmt.Sprintf("log/%s_err.log", name)) if err != nil { log.LogError(err) return err } fout, err := os.Create(fmt.Sprintf("log/%s_trace.log", name)) if err != nil { log.LogError(err) return err } cmd := exec.Command(startapp, "-m", fmt.Sprintf("%s:%d", context.Host, context.Port), "-l", context.LocalIP, "-o", context.OuterIP, "-d", strconv.Itoa(int(appuid)), "-t", typ, "-s", startargs) cmd.Stdout = fout cmd.Stderr = ferr err = cmd.Start() if err != nil { log.LogFatalf(err) return err } log.TraceInfo("master", "app start ", typ, ",", strconv.Itoa(int(appuid))) atomic.AddInt32(&Load, 1) context.waitGroup.Wrap(func() { cmd.Wait() ferr.Close() fout.Close() log.LogMessage(name, " is quit") atomic.AddInt32(&Load, -1) }) return nil }
func (a *Account) Do() { log.LogMessage("start db thread, total:", a.pools) for i := 0; i < a.pools; i++ { id := i db.wg.Wrap(func() { a.work(id) }) } }
/* 选择数据库 */ func (conn *MySql) UseDB(db string) (err error) { if _, err = conn.Exec(fmt.Sprintf("use `%s`", db)); err != nil { return err } log.LogMessage("use db:", db) return }
func (m *Master) Start() { context = m if !m.Agent { log.TraceInfo("master", "start") tcpListener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", m.Host, m.Port)) if err != nil { log.LogError(err) log.LogFatalf(err) } m.tcpListener = tcpListener tcpserver := &tcp_server{} m.waitGroup.Wrap(func() { util.TCPServer(m.tcpListener, tcpserver) }) } if !m.Agent && m.ConsolePort != 0 { StartConsoleServer(m) log.LogMessage("console start at:", m.ConsolePort) } if m.Agent { log.TraceInfo("master agent", "start") m.agent = &Agent{} m.agent.Connect(m.Host, m.Port, true, m.ConnectToMaster) } else { m.agentlist = NewAgentList() m.waitfor = true if m.WaitAgents == 0 { m.waitfor = false StartApp(m) } } }
func (a *Account) Login(mailbox rpc.Mailbox, msg *rpc.Message) (errcode int32, reply *rpc.Message) { args := &c2s.Enterbase{} if server.Check(server.ParseProto(msg, args)) { return 0, nil } if App.Login.checkClient(args.GetUser(), args.GetKey()) { if pl := App.Players.AddPlayer(mailbox.Id); pl != nil { log.LogMessage("add player:", mailbox) pl.Account = args.GetUser() pl.State = STATE_LOGGED if args.GetRolename() != "" { pl.ChooseRole = args.GetRolename() server.Check(App.DbBridge.selectUser(mailbox, pl.Account, args.GetRolename(), int(args.GetRoleindex()))) return 0, nil } server.Check(App.DbBridge.getUserInfo(mailbox, args.GetUser())) return 0, nil } log.LogError("player add failed", mailbox) return 0, nil } else { log.LogDebug(args.GetUser(), args.GetKey()) err := &s2c.Error{} err.ErrorNo = proto.Int32(share.ERROR_LOGIN_FAILED) server.Check(server.MailTo(nil, &mailbox, "Login.Error", err)) return 0, nil } }
func (this *Config) load() { ids := helper.GetConfigIds("conf_configuration.csv") if len(ids) == 0 { log.LogWarning("conf_configuration.csv file load failed") return } this.configMap = make(map[string]*KeyVal, len(ids)) for _, id := range ids { conf := &KeyVal{} if err := helper.LoadStructByFile("conf_configuration.csv", id, conf); err != nil { log.LogFatalf(err) continue } this.configMap[conf.UniqueName] = conf } log.LogMessage("conf_configuration.csv file load ok") ids = helper.GetConfigIds("conf_bp_ratio.csv") if len(ids) == 0 { log.LogWarning("conf_bp_ratio.csv file load failed") return } for _, id := range ids { conf := &KeyVal{} tmp := &PropRatio{} if err := helper.LoadStructByFile("conf_bp_ratio.csv", id, tmp); err != nil { log.LogFatalf(err) continue } conf.UniqueName = "bp_" + tmp.ID conf.Value = tmp.BTRatio this.configMap[conf.UniqueName] = conf } log.LogMessage("conf_bp_ratio.csv file load ok") }
func (s *Scene) OnRemove(self Entityer, sender Entityer, index int) int { log.LogMessage("scene remove obj", sender.GetObjId()) //解除所有的心跳 App.DeatchBeat(sender) self.GetExtraData("cell").(*cell).RemoveObject(sender) return 1 }
//主循环 func (svr *Server) Wait() { go Run(svr) log.LogMessage("server debug:", svr.Debug) //启动调试 if svr.Debug { go func() { log.LogMessage("pprof start at:", svr.PProfPort) if err := http.ListenAndServe(fmt.Sprintf("localhost:%d", svr.PProfPort), nil); err != nil { log.LogMessage("pprof start failed:", err) } }() } <-svr.exitChannel log.TraceInfo(svr.Name, "is shutdown") if svr.globaldataserver { //保存global data log.TraceInfo(svr.Name, "save global data") if err := svr.SaveGlobalData(true, true); err != nil { log.LogError(err) } log.TraceInfo(svr.Name, "save global data, ok") } //通知app进程即将退出 if svr.apper.OnShutdown() { svr.Shutdown() } <-svr.shutdown if svr.noder != nil { svr.noder.Close() } if svr.clientListener != nil { svr.clientListener.Close() } if svr.rpcListener != nil { svr.rpcListener.Close() } svr.WaitGroup.Wait() log.TraceInfo(svr.Name, " stopped") //等待日志写入完毕 <-time.After(time.Second) log.CloseLogger() }
//加载全局数据 func (gd *GlobalDataHelper) LoadGlobalData() error { core.AddDispatchNoName(gd, DP_FRAME) log.LogMessage("begin load global data") db := GetAppByType("database") if db == nil { return ErrAppNotFound } return db.CallBack(nil, "Database.LoadObjectByName", gd.OnLoadGlobalData, core.globalset, "GlobalData", share.DBParams{}) }
func NewTableSync(mb rpc.Mailbox) *TableSync { if tt == nil { panic("table transporter not set") } log.LogMessage("table sync proto:", tt.GetCodecInfo()) ts := &TableSync{} ts.mailbox = mb return ts }
//输出调试信息 func (p *Pool) DebugInfo(intervalid TimerID, count int32, args interface{}) { info := make([]string, 0, 16) info = append(info, "object pool memory status:") info = append(info, "###########################################") for k, v := range p.pool { info = append(info, fmt.Sprintf("pool:%s, cached:%d", k, v.Len())) } info = append(info, "###########################################") log.LogMessage(strings.Join(info, "\n")) }
func (client *Client) Go() { var err error for err == nil { select { case call := <-client.sendqueue: err := client.send(call) if err != nil { log.LogError("send error:", err) log.LogMessage("quit sending loop") return } default: if client.shutdown || client.closing { log.LogMessage("quit sending loop") return } time.Sleep(time.Millisecond) } } }
func (a *Account) ClearStatus(mailbox rpc.Mailbox, msg *rpc.Message) (errcode int32, reply *rpc.Message) { r := server.NewMessageReader(msg) serverid, err := r.ReadString() if server.Check(err) { return 0, nil } server.Check2(db.sql.Exec("UPDATE `role_info` SET `status`=?, `serverid`=? WHERE `status`=? and `serverid`=?", 0, "", 1, serverid)) log.LogMessage("clear server:", serverid) return 0, nil }
func NewViewport(p Entityer, mailbox rpc.Mailbox) *Viewport { if vt == nil { panic("viewport transport not set") } log.LogMessage("viewport proto:", vt.GetCodecInfo()) vp := &Viewport{} vp.Views = make(map[int32]*ViewportData) vp.Owner = p vp.mailbox = mailbox return vp }
func NewPropSync(mb rpc.Mailbox, objid ObjectID) *PropSync { if pt == nil { panic("prop transport not set") } log.LogMessage("prop sync proto:", pt.GetCodecInfo()) ts := &PropSync{} ts.mailbox = mb ts.objid = objid return ts }
func (mp *master_peer) Handle(id uint16, msgbody []byte) error { switch id { case share.M_ADD_SERVER: var as share.AddApp if err := share.DecodeMsg(msgbody, &as); err != nil { return err } AddApp(as.Type, as.Id, as.Name, as.Host, as.Port, as.ClientHost, as.ClientPort, as.Ready, as.EnableGlobalData) case share.M_REMOVE_SERVER: var rs share.RemoveApp if err := share.DecodeMsg(msgbody, &rs); err != nil { return err } RemoveAppById(rs.Id) case share.M_SERVER_LIST: var sl share.AppInfo if err := share.DecodeMsg(msgbody, &sl); err != nil { return err } for _, a := range sl.Apps { AddApp(a.Type, a.Id, a.Name, a.Host, a.Port, a.ClientHost, a.ClientPort, a.Ready, a.EnableGlobalData) } case share.M_HEARTBEAT: data, err := util.CreateMsg(nil, []byte{}, share.M_HEARTBEAT) if err != nil { log.LogFatalf(err) } core.noder.Send(data) case share.M_READY: var ready share.AppReady if err := share.DecodeMsg(msgbody, &ready); err != nil { return err } app := GetAppById(ready.Id) if app != nil { app.SetReady(true) } else { log.LogFatalf("app not found") } case share.M_MUSTAPPREADY: { log.LogMessage("must app ready") core.MustReady() } case share.M_SHUTDOWN: core.Closing = true close(core.exitChannel) return nil } core.Emitter.Push(MASERTINMSG, map[string]interface{}{"msg": MasterMsg{id, msgbody}}, false) return nil }
func (a *Account) ClearPlayerStatus(mailbox rpc.Mailbox, info share.ClearUser) error { return a.process("ClearPlayerStatus", func() error { c := db.DB.C(ROLEINFO) c.Update(bson.M{"rolename": info.Name}, bson.M{"$set": bson.M{"status": 0, "serverid": ""}}) c.Update(bson.M{"rolename": info.Name}, bson.M{"$set": bson.M{"status": 0, "serverid": ""}}) log.LogMessage("player clear status,", info.Name) return nil }) }
func (this *cell) Delete() { if ps, ok := this.Objects[PLAYER]; ok { if len(ps) > 0 { for _, p := range ps { this.RemoveObject(p) } } } App.Destroy(this.scene.GetObjId()) log.LogMessage("cell deleted,", this.id) }