예제 #1
0
파일: account.go 프로젝트: mysll/flynet
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)
		}
	}
}
예제 #2
0
//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")
}
예제 #3
0
파일: remoteapp.go 프로젝트: mysll/flynet
//处理由客户端的发起远程调用
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
}
예제 #4
0
파일: thread.go 프로젝트: mysll/flynet
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)
		}
	}
}
예제 #5
0
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")
}
예제 #6
0
파일: areas.go 프로젝트: mysll/flynet
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
}
예제 #7
0
파일: playerlist.go 프로젝트: mysll/flynet
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
}
예제 #8
0
파일: entityer.go 프로젝트: mysll/flynet
//注册函数
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
}
예제 #9
0
//数据库加载回调
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")
}
예제 #10
0
파일: areas.go 프로젝트: mysll/flynet
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)
}
예제 #11
0
파일: client.go 프로젝트: mysll/flynet
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())
}
예제 #12
0
파일: cell.go 프로젝트: mysll/flynet
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
}
예제 #13
0
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
}
예제 #14
0
파일: account.go 프로젝트: mysll/flynet
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) })
	}
}
예제 #15
0
파일: mysql.go 프로젝트: mysll/flynet
/*
选择数据库
*/
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
}
예제 #16
0
파일: master.go 프로젝트: mysll/flynet
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)
		}
	}
}
예제 #17
0
파일: account.go 프로젝트: mysll/flynet
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
	}
}
예제 #18
0
파일: config.go 프로젝트: mysll/flynet
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")

}
예제 #19
0
파일: scene.go 프로젝트: mysll/flynet
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
}
예제 #20
0
파일: server.go 프로젝트: mysll/flynet
//主循环
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()
}
예제 #21
0
//加载全局数据
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{})
}
예제 #22
0
파일: table_sync.go 프로젝트: mysll/flynet
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
}
예제 #23
0
파일: entity_pool.go 프로젝트: mysll/flynet
//输出调试信息
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"))
}
예제 #24
0
파일: client.go 프로젝트: mysll/flynet
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)
		}
	}
}
예제 #25
0
파일: account.go 프로젝트: mysll/flynet
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
}
예제 #26
0
파일: viewport.go 프로젝트: mysll/flynet
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
}
예제 #27
0
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
}
예제 #28
0
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

}
예제 #29
0
파일: account.go 프로젝트: mysll/flynet
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
	})
}
예제 #30
0
파일: cell.go 프로젝트: mysll/flynet
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)
}