func KVQuery(db *rpcplus.Client, table, uid string, value interface{}) (exist bool, err error) { //ts("KVQuery", table, uid) //defer te("KVQuery", table, uid) var reply protobuf.DBQueryResult err = db.Call("DBServer.Query", protobuf.DBQuery{table, uid}, &reply) if err != nil { logger.Error("KVQuery Error On Query %s : %s (%s)", table, uid, err.Error()) return } switch reply.Code { case protobuf.Ok: var dst []byte dst, err = snappy.Decode(nil, reply.Value) if err != nil { logger.Error("KVQuery Unmarshal Error On snappy.Decode %s : %s (%s)", table, uid, err.Error()) return } switch value.(type) { case gp.Message: err = gp.Unmarshal(dst, value.(gp.Message)) if err != nil { logger.Error("KVQuery Unmarshal Error On Query %s : %s (%s)", table, uid, err.Error()) return } case *[]byte: *(value.(*[]byte)) = dst default: logger.Error("KVQuery args type error %v", value) return } exist = true return case protobuf.NoExist: return } logger.Error("KVQuery Unknow DBReturn %d", reply.Code) return false, fmt.Errorf("KVQuery Unknow DBReturn %d", reply.Code) }
func (conn *ProtoBufConn) mux() { for { select { case r := <-conn.send: //logger.Debug("writeRequest %v", r) buf, err := proto.Marshal(r) if err != nil { logger.Error("ProtoBufConn Marshal Error %s", err.Error()) continue } //logger.Debug(" mux: %v", buf) //dst, err := snappy.Encode(nil, buf) dst := buf //logger.Debug(" dst mux: %v", dst) if err != nil { logger.Error("ProtoBufConn snappy.Encode Error %s", err.Error()) continue } conn.c.SetWriteDeadline(time.Now().Add(ConnWriteTimeOut)) dstBuffer := new(bytes.Buffer) err = binary.Write(dstBuffer, binary.LittleEndian, int32(len(dst))) if err != nil { logger.Error("ProtoBufConn Write Error %s", err.Error()) continue } conn.c.SetWriteDeadline(time.Now().Add(ConnWriteTimeOut)) _, err = dstBuffer.Write(dst) if err != nil { logger.Error("ProtoBufConn Write Error %s", err.Error()) continue } conn.c.SetWriteDeadline(time.Now().Add(ConnWriteTimeOut)) conn.c.WriteMessage(dstBuffer.Bytes()) if err != nil { logger.Error("ProtoBufConn Write Error %s", err.Error()) continue } case <-conn.exit: return } } }
func StartServices(cfg *config.SvrConfig, id *uint64) *FightServer { fightServer = &FightServer{} fightServer = &FightServer{ rpcServer: server.NewServer(), battles: make(map[string]*Battle), } fightServer.rpcServer.Register(fightServer) fightServer.rpcServer.RegCallBackOnConn( func(conn server.RpcConn) { fightServer.onConn(conn) }, ) listener, err := net.Listen("tcp", cfg.FsHost[*id]) if err != nil { logger.Fatal("net.Listen: %s", err.Error()) } fightServer.id = *id go func() { for { //For Client///////////////////////////// time.Sleep(time.Millisecond * 5) conn, err := listener.Accept() if err != nil { logger.Error("fightserver StartServices %s", err.Error()) break } go func() { rpcConn := server.NewTCPSocketConn(fightServer.rpcServer, conn, 1000, 0, 1) rpcConn.SetResultServer("Connector") defer func() { if r := recover(); r != nil { logger.Error("player rpc runtime error begin:", r) debug.PrintStack() rpcConn.Close() logger.Error("player rpc runtime error end ") } }() fightServer.rpcServer.ServeConn(rpcConn) }() } }() return fightServer }
func Register_lua_rpc_RpcClient_Call(L *lua.LState) int { ud := L.CheckUserData(1) method := L.CheckString(2) args := L.CheckString(3) if L.GetTop() > 4 { argstyp := L.CheckString(5) reptyp := L.CheckString(6) //logger.Debug("Register_lua_rpc_RpcClient_Call(%v,%v,%v,%v,%v,%v)", ud, method, args, "", argstyp, reptyp) if v, ok := ud.Value.(*rpc.Client); ok { typArgs := DefaultScript.GetPbType(argstyp) typRep := DefaultScript.GetPbType(reptyp) valueArgs := reflect.New(typArgs) valueRep := reflect.New(typRep) if valueRep.Interface() != nil && valueArgs.Interface() != nil { if value, ok := (valueArgs.Interface()).(proto.Message); ok { proto.Unmarshal([]byte(args), value) repMsg := valueRep.Interface() v.Call(method, value, repMsg) rep, err := proto.Marshal(repMsg.(proto.Message)) if err != nil { logger.Debug("Register_lua_rpc_RpcClient_Call : Marshal Error %v ", valueRep.Interface()) return 0 } L.Replace(4, lua.LString(string(rep))) L.Push(lua.LString(string(rep))) //logger.Debug("Register_lua_rpc_RpcClient_Call (%d): rep %v ", L.GetTop(), string(rep)) return 1 } else { logger.Error("Register_lua_rpc_RpcClient_Call Error type : %v", valueArgs.Interface()) } } else { logger.Error("Register_lua_rpc_RpcClient_Call Error : valueArgs %v, valueRep %v", valueArgs.Interface(), valueRep.Interface()) } } } else { if v, ok := ud.Value.(*rpc.Client); ok { req := []byte(args) rep := []byte("") v.Call(method, &req, &rep) L.Replace(4, lua.LString(string(rep))) L.Push(lua.LString(string(rep))) //logger.Debug("Register_lua_rpc_RpcClient_Call (%d): rep %v ", L.GetTop(), string(rep)) return 1 } } return 0 }
func (self *LuaScript) GetPbType(name string) reflect.Type { if v, ok := self.pbMap[name]; ok { return v } logger.Error("not regist %v in suitablePbMap...", name) return nil }
func CacheCreator(cfg config.CacheConfig) CreateCacheFunc { dns := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port) return func() (c redis.Conn, err error) { var retry uint8 = 0 for { c, err = redis.Dial("tcp", dns) if err == nil { break } logger.Error("Error on Create redis: %s; try: %d/%d", err.Error(), retry, cfg.MaxRetry) if retry >= cfg.MaxRetry { return } retry++ } _, err = c.Do("SELECT", cfg.Index) return } }
func DBCreator(cfg config.MySQLConfig) CreateDBFunc { dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s", cfg.Uname, cfg.Pass, cfg.Host, cfg.Port, cfg.Dbname, cfg.Charset) logger.Info("MySqlDNS: %s", dns) return func() (db *sql.DB, dnsInfo string, err error) { dnsInfo = dns var retry uint8 = 0 for { db, err = sql.Open("mysql", dns) if err == nil { break } logger.Error("Error on Create db: %s; try: %d/%d", err.Error(), retry, cfg.MaxRetry) if retry >= cfg.MaxRetry { return } retry++ } return } }
func Register_lua_db_CachePool_Do(L *lua.LState) int { ud := L.CheckUserData(1) cmd := L.CheckString(2) arg1 := L.CheckString(3) var value []byte var err error if v, ok := ud.Value.(*db.CachePool); ok { if L.GetTop() == 4 { arg2 := L.CheckString(4) value, err = redis.Bytes(v.Do(cmd, arg1, arg2)) } else { value, err = redis.Bytes(v.Do(cmd, arg1)) } } if err == nil { L.Push(lua.LString(string(value))) L.Push(lua.LString("")) } else { if err != nil { L.Push(lua.LString("")) L.Push(lua.LString(err.Error())) } else { L.Push(lua.LString("")) L.Push(lua.LString("not string type value")) } logger.Error("Register_lua_db_CachePool_Do Error : %v, %v", value, err) } return 2 }
func KVWrite(db *rpcplus.Client, table, uid string, value interface{}) (result bool, err error) { //ts("KVWrite", table, uid) //defer te("KVWrite", table, uid) var buf []byte switch value.(type) { case gp.Message: buf, err = gp.Marshal(value.(gp.Message)) if err != nil { logger.Error("KVWrite Error On Marshal %s : %s (%s)", table, uid, err.Error()) return } case []byte: buf = value.([]byte) default: logger.Error("KVWrite args type error %v", value) return } dst, err := snappy.Encode(nil, buf) if err != nil { logger.Error("KVWrite Error On snappy.Encode %s : %s (%s)", table, uid, err.Error()) return } var reply protobuf.DBWriteResult err = db.Call("DBServer.Write", protobuf.DBWrite{table, uid, dst}, &reply) if err != nil { logger.Error("KVWrite Error On Create %s: %s (%s)", table, uid, err.Error()) return } if reply.Code != protobuf.Ok { logger.Error("KVWrite Error On Create %s: %s code (%d)", table, uid, reply.Code) return } result = true return }
func (self *Connector) sendPlayerCountToGateServer() { go func() { defer func() { if r := recover(); r != nil { logger.Info("sendPlayerCountToGateServer runtime error:", r) debug.PrintStack() } }() for { time.Sleep(5 * time.Second) self.l.RLock() playerCount := uint32(len(self.players)) self.l.RUnlock() var ret []byte req := protobuf.SL_UpdatePlayerCount{} req.SetServerId(self.id) req.SetPlayerCount(playerCount) req.SetTcpServerIp(self.listenTcpIp) req.SetHttpServerIp(self.listenHttpIp) //logger.Debug("playerCount %v", playerCount) buf, err := proto.Marshal(&req) if err != nil { logger.Error("Error On Connector.sendPlayerCountToGateServer : %s", err.Error()) return } err = self.loginserver.Call("LoginRpcServer.SL_UpdatePlayerCount", &buf, &ret) if err != nil { logger.Error("Error On LoginRpcServer.SL_UpdatePlayerCount : %s", err.Error()) return } } }() }
func (conn *ProtoBufConn) ApplyProtocol(protocal map[string]int32) { logger.Debug("ApplyProtocol") for key, value := range protocal { protocalMethod := strings.Split(key, "_") if len(protocalMethod) != 2 { logger.Error("rpc: ApplyProtocol ill-formed: %v , no '_' for split key" + key) } conn.protocol[protocalMethod[1]] = uint32(value) } }
func Register_lua_common_WriteObj(L *lua.LState) int { ud := L.CheckUserData(1) buffer := L.CheckString(2) if v, ok := ud.Value.(*server.ProtoBufConn); ok { err := v.WriteObj([]byte(buffer)) if err != nil { logger.Error("lua_server_ProtoBufConn_WriteObj Error : %s", err.Error()) } } return 0 }
func KVDelete(db *rpcplus.Client, table, uid string) (result bool, err error) { //ts("KVDelete", table, uid) //defer te("KVDelete", table, uid) var reply protobuf.DBDelResult err = db.Call("DBServer.Delete", protobuf.DBDel{table, uid}, &reply) if err != nil { logger.Error("KVDelete Error On %s: %s (%s)", table, uid, err.Error()) return } if reply.Code != protobuf.Ok { logger.Error("KVDelete Error On %s: %s code (%d)", table, uid, reply.Code) return } result = true return }
func Register_lua_server_RpcConn_Call(L *lua.LState) int { ud := L.CheckUserData(1) cmd := L.CheckNumber(2) buffer := L.CheckString(3) if v, ok := ud.Value.(*server.RpcConn); ok { err := (*v).Call(uint32(cmd), []byte(buffer)) if err != nil { logger.Error("lua_server_ProtoBufConn_WriteObj Error : %s", err.Error()) } } return 0 }
func (server *Server) ListenAndServe(tcpAddr string, context interface{}) { //logger.Debug("ListenAndServe :[%s]", tcpAddr) listener, err := net.Listen("tcp", tcpAddr) if err != nil { logger.Fatal("net.Listen: %s", err.Error()) } go func() { for { //For Client///////////////////////////// //time.Sleep(time.Millisecond * 5) conn, err := listener.Accept() if err != nil { logger.Error("gateserver StartServices %s", err.Error()) break } if context != nil { go func(context interface{}) { for _, v := range server.onConn { v(context) } server.ServeConnWithContext(conn, context) conn.Close() for _, v := range server.onConn { v(context) } }(context) } else { go func() { for _, v := range server.onConn { v(nil) } server.ServeConn(conn) conn.Close() for _, v := range server.onConn { v(nil) } }() } } listener.Close() }() }
func (server *Server) ListenAndServe(tcpAddr string, httpAddr string) { //logger.Debug("ListenAndServe :[%s] - [%s]", tcpAddr, httpAddr) listener, err := net.Listen("tcp", tcpAddr) if err != nil { logger.Fatal("net.Listen: %s", err.Error()) } go func() { for { //For Client///////////////////////////// time.Sleep(time.Millisecond * 5) conn, err := listener.Accept() if err != nil { logger.Error("gateserver StartServices %s", err.Error()) break } go func() { rpcConn := NewTCPSocketConn(server, conn, 4, 30, 1) defer func() { if r := recover(); r != nil { logger.Error("player rpc runtime error begin:", r) debug.PrintStack() rpcConn.Close() logger.Error("player rpc runtime error end ") } }() server.ServeConn(rpcConn) }() } }() go func() { http.HandleFunc("/", server.wsServeConnHandler) http.ListenAndServe(httpAddr, nil) }() }
func (server *Server) sendErrorResponse(req *RequestWrap, conn RpcConn, errmsg string) { // Encode the response header resp := protobuf.RpcErrorResponse{} resp.Cmd = req.Cmd resp.Text = &errmsg err := conn.WriteObj(resp) if err != nil { logger.Error("rpc: writing ErrorResponse: %s", err.Error()) sysdebug.PrintStack() } }
func StartServices(self *DBServer, listener net.Listener) { rpcServer := rpc.NewServer() rpcServer.Register(self) for { conn, err := listener.Accept() if err != nil { logger.Error("StartServices %s", err.Error()) break } go func() { rpcServer.ServeConn(conn) conn.Close() }() } }
func Register_lua_rpc_RpcClient_newClass(L *lua.LState) int { addr := L.CheckString(1) rpcConn, err := net.Dial("tcp", addr) for { if err == nil { break } logger.Error("rpcConn Connect Error : %v", err.Error()) time.Sleep(time.Second * 3) rpcConn, err = net.Dial("tcp", addr) } ud := L.NewUserData() ud.Value = rpc.NewClient(rpcConn) L.SetMetatable(ud, L.GetTypeMetatable(luaRpcClientTypeName)) L.Push(ud) return 1 }
func (server *Server) CallLua(conn RpcConn, buf []byte, cmd uint32) (err error) { //logger.Debug("CallLua %v", method) var mtype *methodType var table *lua.LTable // Look up the request. server.mu.RLock() for key, value := range server.serviceMap { service := value if service == nil { err = errors.New("CallLua: rpc: can't find service " + key) server.mu.RUnlock() return } mtype = service.method[cmd] table = service.rcvr.Interface().(*lua.LTable) if mtype != nil { break //find the cmd } } server.mu.RUnlock() if mtype == nil { err = errors.New("CallLua: can't find any method " + strconv.Itoa(int(cmd))) return } ud := server.state.NewUserData() ud.Value = &conn server.state.SetMetatable(ud, server.state.GetTypeMetatable(luaRpcConnTypeName)) err2 := server.state.CallByParam(lua.P{ Fn: mtype.luaMethod, NRet: 1, Protect: true, }, table, ud, lua.LString(string(buf))) if err2 != nil { logger.Error("CallLua Error : %s", err2.Error()) } server.state.Get(-1) server.state.Pop(1) return }
func (server *Server) CallLua(req *[]byte, ret *[]byte, method string) (err error) { //logger.Debug("CallLua %v", method) serviceMethod := strings.Split(method, ".") if len(serviceMethod) != 2 { err = errors.New("CallLua: service/method request ill-formed: " + method) return } // Look up the request. server.mu.Lock() service := server.serviceMap[serviceMethod[0]] server.mu.Unlock() if service == nil { err = errors.New("CallLua: can't find service " + method) return } mtype := service.method[serviceMethod[1]] if mtype == nil { err = errors.New("CallLua: can't find method " + method) return } err2 := server.state.CallByParam(lua.P{ Fn: mtype.luaFn, NRet: 1, Protect: true, }, service.rcvr.Interface().(*lua.LTable), lua.LString(string(*req)), lua.LString(string(*ret))) if err2 != nil { logger.Error("CallLua Error : %s", err2.Error()) } returnRsult := server.state.CheckString(-1) server.state.Pop(1) *ret = []byte(returnRsult) return }
func Register_lua_server_Server_RegCallBackOnConn(L *lua.LState) int { ud := L.CheckUserData(1) luaFn := L.CheckFunction(2) if v, ok := ud.Value.(*server.Server); ok { v.RegCallBackOnConn( func(conn server.RpcConn) { udConn := L.NewUserData() udConn.Value = &conn L.SetMetatable(udConn, L.GetTypeMetatable(luaRpcConnTypeName)) err2 := L.CallByParam(lua.P{ Fn: luaFn, NRet: 0, Protect: true, }, udConn) if err2 != nil { logger.Error("RegCallBackOnConn Error : %s", err2.Error()) } }, ) } return 0 }
func CreateConnectorServerForClient(cfg config.SvrConfig) *Connector { db.Init() var authCfg config.AuthConfig if err := config.ReadConfig("etc/authserver.json", &authCfg); err != nil { logger.Fatal("load config failed, error is: %v", err) } authConn, err := net.Dial("tcp", authCfg.AuthHost) if err != nil { logger.Fatal("connect logserver failed %s", err.Error()) } var gsCfg config.LoginConfig if err = config.ReadConfig("etc/loginserver.json", &gsCfg); err != nil { logger.Fatal("load config failed, error is: %v", err) } gsConn, err := net.Dial("tcp", gsCfg.LoginHost) if err != nil { logger.Fatal("%s", err.Error()) } pConnector = &Connector{ m: make(map[uint32]serverInfo), authserver: rpc.NewClient(authConn), loginserver: rpc.NewClient(gsConn), rpcServer: server.NewServer(), players: make(map[uint64]*Player), playersbyid: make(map[string]*Player), } //初始化cache logger.Info("Init Cache %v", authCfg.MainCacheProfile) pConnector.maincache = db.NewCachePool(authCfg.MainCacheProfile) pConnector.rpcServer.ApplyProtocol(protobuf.CS_Protocol_value) pConnector.rpcServer.Register(pConnector) pConnector.rpcServer.RegCallBackOnConn( func(conn server.RpcConn) { pConnector.onConn(conn) }, ) pConnector.rpcServer.RegCallBackOnDisConn( func(conn server.RpcConn) { pConnector.onDisConn(conn) }, ) pConnector.rpcServer.RegCallBackOnCallBefore( func(conn server.RpcConn) { conn.Lock() }, ) pConnector.rpcServer.RegCallBackOnCallAfter( func(conn server.RpcConn) { conn.Unlock() }, ) //开始对fightserver的RPC服务 pConnector.FsMgr.Init(pConnector.rpcServer, cfg) listener, err := net.Listen("tcp", cfg.TcpHost) if err != nil { logger.Fatal("net.Listen: %s", err.Error()) } pConnector.id = cfg.ServerID pConnector.listenTcpIp = cfg.TcpHost pConnector.listenHttpIp = cfg.HttpHost pConnector.sendPlayerCountToGateServer() go func() { for { //For Client///////////////////////////// time.Sleep(time.Millisecond * 5) conn, err := listener.Accept() if err != nil { logger.Error("cns StartServices %s", err.Error()) break } go func() { rpcConn := server.NewTCPSocketConn(pConnector.rpcServer, conn, 128, 45, 1) defer func() { if r := recover(); r != nil { logger.Error("player rpc runtime error begin:", r) debug.PrintStack() rpcConn.Close() logger.Error("player rpc runtime error end ") } }() pConnector.rpcServer.ServeConn(rpcConn) }() } }() http.HandleFunc("/", wsServeConnHandler) http.ListenAndServe(cfg.HttpHost, nil) return pConnector }