func (conn *ProtoBufConn) ReadRequest(req *protobuf.Packet) error { conn.c.SetReadDeadline(time.Now().Add(ConnReadTimeOut)) dst, err := conn.c.ReadMessage() if err != nil { logger.Debug("ReadRequest Read binary Err: %v", err) return err } //dst, err := snappy.Decode(nil, dstBuffer.Bytes()) if err != nil { logger.Debug("ReadRequest Decode Err: %v", err) return err } conn.last_time = time.Now().Unix() //logger.Info("ReadRequest dst: %v", dst) err = proto.Unmarshal(dst, req) conn.msg_id = req.GetId() return err }
func (server *Server) ApplyProtocol(protocal map[string]int32) { logger.Debug("ApplyProtocol") for key, value := range protocal { cmd := key[1:len(key)] server.protocol[cmd] = uint32(value) } for key, value := range server.protocol { logger.Debug("ApplyProtocol %s, %d", key, value) } }
func wsServeConnHandler(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { fmt.Fprintln(w, "rpc: error") return } logger.Debug("wsServeConnHandler : %v", r.FormValue("method")) conn, err := upgrader.Upgrade(w, r, nil) if err != nil { logger.Info("Upgrade:", err.Error()) conn, bufrw, err := w.(http.Hijacker).Hijack() if err != nil { logger.Debug("rpc hijacking %v : %v", r.RemoteAddr, err.Error()) return } else { httpConn := server.NewTCPSocketConn(pConnector.rpcServer, conn, 1, 1, 1) logger.Debug("rpc hijacking %v : %v", r.RemoteAddr, r.FormValue("method")) fmt.Fprintln(w, "rpc: hello") buf := make([]byte, 10) for i := 0; i < len(buf); i++ { buf[i] = byte(i) } _, err = bufrw.Write(buf) if err == nil { err = bufrw.Flush() } if err != nil { fmt.Printf("ResponseError: %s\\n", err) } else { fmt.Println("Bye, Jack!") } logger.Debug("httpConn WriteObj %v", httpConn.GetRemoteIp()) } return } rpcConn := server.NewWebSocketConn(pConnector.rpcServer, *conn, 128, 45, 2) defer func() { rpcConn.Close() // 客户端退出减去计数 }() pConnector.rpcServer.ServeConn(rpcConn) }
func CheckSessionKey(skey string) bool { if len(skey) != 70 { return false } b := make([]uint32, 5) var s string guid := skey[:36] _, err := fmt.Sscanf(skey, "%x-%x-%x-%x-%x--%s", &b[0], &b[1], &b[2], &b[3], &b[4], &s) if err != nil { logger.Debug("err : %v", err.Error()) return false } info1 := make([]byte, 4) binary.BigEndian.PutUint32(info1, b[0]) info2 := make([]byte, 4) binary.BigEndian.PutUint16(info2[:2], uint16(b[1])) binary.BigEndian.PutUint16(info2[2:], uint16(b[2])) c, _ := rc4.NewCipher([]byte{0x0c, info1[2], info1[3], info1[0]}) tmp := make([]byte, 4) c.XORKeyStream(tmp, info1) if binary.BigEndian.Uint32(tmp) != b[3] { return false } c.XORKeyStream(tmp, info2) if binary.BigEndian.Uint32(tmp) != b[4] { return false } h := md5.New() io.WriteString(h, guid) io.WriteString(h, MD5key) if s != fmt.Sprintf("%x", h.Sum(nil)) { logger.Debug("%s, %x", guid, h.Sum(nil)) return false } return true }
func (self *FightServer) StartBattle(conn server.RpcConn, player protobuf.PlayerBaseInfo) error { logger.Debug("StartBattle") id := common.GenUUID(fmt.Sprintf("%d", atomic.AddUint64(&self.id, 1))) base := &protobuf.BattleInfo{} base.SetBid(id) partners := make([]*protobuf.CreatureBaseInfo, 0, 10) mosters := make([]*protobuf.CreatureBaseInfo, 0, 10) partners = append(partners, ConvertPlayerToCreature(&player)) mosters = append(mosters, RandomCreature("1"), RandomCreature("2"), RandomCreature("3"), RandomCreature("4"), RandomCreature("5")) base.SetPartner(partners) base.SetEnemy(mosters) base.SetAttackunits(make([]*protobuf.AttackInfo, 0, 10)) base.SetSpells(make([]*protobuf.SpellInfo, 0, 10)) b := &Battle{BattleInfo: base} //WriteResult(conn, base) notify := &protobuf.NotifyBattleStart{} notify.SetBid(base.GetBid()) notify.SetPartner(partners) notify.SetEnemy(mosters) WriteResult(conn, notify) self.addBattle(b) return nil }
func Register_lua_db(L *lua.LState) { logger.Debug("Register_lua_db") DefaultScript.RegisterGlobalFunction(luaDBInitFuncName, Register_lua_db_DBInit) DefaultScript.RegisterGlobalFunction(luaDBQueryFuncName, Register_lua_db_DBQuery) DefaultScript.RegisterGlobalFunction(luaDBWriteFuncName, Register_lua_db_DBWrite) DefaultScript.RegisterGlobalFunction(luaDBDeleteFuncName, Register_lua_db_DBDelete) }
func Register_lua_common(L *lua.LState) { logger.Debug("Register_lua_common") DefaultScript.RegisterGlobalFunction(luaWatchSystemSignalFuncName, Register_lua_common_WatchSystemSignal) DefaultScript.RegisterGlobalFunction(luaWriteObjFuncName, Register_lua_common_WriteObj) DefaultScript.RegisterGlobalFunction(luaSetIntervalFuncName, Register_lua_common_SetInterval) DefaultScript.RegisterGlobalFunction(luaClearIntervalFuncName, Register_lua_common_ClearInterval) }
func Register_lua_json(L *lua.LState) { logger.Debug("Register_lua_json") js := &Json{} mt := DefaultScript.RegisterGlobalClassBegin(luaJsonTypeName, js) DefaultScript.RegisterGlobalClassFunction(mt, "Decode", L.NewFunction(apiDecode)) DefaultScript.RegisterGlobalClassFunction(mt, "Encode", L.NewFunction(apiEncode)) DefaultScript.RegisterGlobalClassEnd(luaJsonTypeName) }
func (self *FightServer) CalculateBattleResult(conn server.RpcConn, queue protobuf.BattleAttackQueue) error { logger.Debug("CalculateBattleResult") _, exist := self.battles[queue.GetBid()] if !exist { return nil } attackunits := self.battles[queue.GetBid()].GetAttackunits() for _, att := range queue.GetAttackunits() { attackunits = append(attackunits, att) } spells := self.battles[queue.GetBid()].GetSpells() for _, att := range queue.GetSpells() { spells = append(spells, att) } self.battles[queue.GetBid()].SetAttackunits(attackunits) self.battles[queue.GetBid()].SetSpells(spells) WriteResult(conn, self.battles[queue.GetBid()].BattleInfo) end := true for _, p := range self.battles[queue.GetBid()].GetPartner() { stat := p.GetStat() if stat.GetHP() > 0 { end = false } } var exp uint32 exp = 0 if !end { exp = 100 for _, e := range self.battles[queue.GetBid()].GetEnemy() { stat := e.GetStat() if stat.GetHP() > 0 { end = false } } } if end { for _, p := range self.battles[queue.GetBid()].GetPartner() { notify := &protobuf.NotifyBattleEnd{} notify.SetPlayerlid(p.GetUid()) notify.SetExp(exp) WriteResult(conn, notify) } } return nil }
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_rpc_RpcServer(L *lua.LState) { logger.Debug("Register_server_%s", luaRpcServerTypeName) svc := &rpc.Server{} mt := DefaultScript.RegisterGlobalClassBegin(luaRpcServerTypeName, svc) DefaultScript.RegisterGlobalClassFunction(mt, "new", L.NewFunction(Register_lua_rpc_RpcServer_newClass)) DefaultScript.RegisterGlobalClassFunction(mt, "__create", L.NewFunction(Register_lua_rpc_RpcServer_newClass)) DefaultScript.RegisterGlobalClassFunction(mt, "__cname", lua.LString(luaRpcServerTypeName)) DefaultScript.RegisterGlobalClassFunction(mt, "__ctype", lua.LNumber(1)) DefaultScript.RegisterGlobalClassFunction(mt, "__index", L.SetFuncs(L.NewTable(), indexRpcServerMethods)) DefaultScript.RegisterGlobalClassEnd(luaRpcServerTypeName) }
func Register_lua_db_CachePool(L *lua.LState) { logger.Debug("Register_lua_common") cache := db.CachePool{} mt := DefaultScript.RegisterGlobalClassBegin(luaCachePoolTypeName, cache) DefaultScript.RegisterGlobalClassFunction(mt, "new", L.NewFunction(Register_lua_db_CachePool_newClass)) DefaultScript.RegisterGlobalClassFunction(mt, "__create", L.NewFunction(Register_lua_db_CachePool_newClass)) DefaultScript.RegisterGlobalClassFunction(mt, "__cname", lua.LString(luaCachePoolTypeName)) DefaultScript.RegisterGlobalClassFunction(mt, "__ctype", lua.LNumber(1)) DefaultScript.RegisterGlobalClassFunction(mt, "__index", L.SetFuncs(L.NewTable(), indexCachePoolMethods)) DefaultScript.RegisterGlobalClassEnd(luaCachePoolTypeName) }
func Register_lua_server_RpcConn(L *lua.LState) { logger.Debug("Register_server_%s", luaRpcConnTypeName) conn := &server.ProtoBufConn{} mt := DefaultScript.RegisterGlobalClassBegin(luaRpcConnTypeName, conn) DefaultScript.RegisterGlobalClassFunction(mt, "new", L.NewFunction(Register_lua_server_RpcConn_newClass)) DefaultScript.RegisterGlobalClassFunction(mt, "__create", L.NewFunction(Register_lua_server_RpcConn_newClass)) DefaultScript.RegisterGlobalClassFunction(mt, "__cname", lua.LString(luaRpcConnTypeName)) DefaultScript.RegisterGlobalClassFunction(mt, "__ctype", lua.LNumber(1)) DefaultScript.RegisterGlobalClassFunction(mt, "__index", L.SetFuncs(L.NewTable(), indexRpcConnMethods)) DefaultScript.RegisterGlobalClassEnd(luaRpcConnTypeName) }
func RegisterOsgModule(L *lua.LState) int { logger.Debug("osg module Loader") Register_lua_json(L) Register_lua_common(L) Register_lua_db(L) Register_lua_db_CachePool(L) Register_lua_rpc_RpcClient(L) Register_lua_rpc_RpcServer(L) Register_lua_server_RpcConn(L) Register_lua_server_Server(L) return 0 }
func RegisterProtobufModule(L *lua.LState) int { logger.Debug("protobuf module Loader") DefaultScript.ExecuteScriptFile("script/protobuf/descriptor.lua") DefaultScript.ExecuteScriptFile("script/protobuf/text_format.lua") DefaultScript.ExecuteScriptFile("script/protobuf/containers.lua") DefaultScript.ExecuteScriptFile("script/protobuf/listener.lua") DefaultScript.ExecuteScriptFile("script/protobuf/type_checkers.lua") DefaultScript.ExecuteScriptFile("script/protobuf/wire_format.lua") DefaultScript.ExecuteScriptFile("script/protobuf/encoder.lua") DefaultScript.ExecuteScriptFile("script/protobuf/decoder.lua") DefaultScript.ExecuteScriptFile("script/protobuf/protobuf.lua") return 0 }
func (c Conn) ReadMessage() ([]byte, error) { var size uint32 switch c.client_type { case 1: err := binary.Read(c.tcp_socket, binary.LittleEndian, &size) if err != nil { logger.Debug("ReadMessage err 1: %v", err.Error()) return nil, err } buf := make([]byte, size) c.SetReadDeadline(time.Now().Add(ConnReadTimeOut)) _, err = io.ReadFull(c.tcp_socket, buf) if err != nil { logger.Debug("ReadMessage err 2: %v", err.Error()) return nil, err } return buf, err case 2: _, buf, err := c.web_socket.ReadMessage() dstBuffer := bytes.NewBuffer(buf) c.SetReadDeadline(time.Now().Add(ConnReadTimeOut)) err = binary.Read(dstBuffer, binary.LittleEndian, &size) return dstBuffer.Bytes(), err default: return nil, errors.New("ProtoBufConn: err client_type unknown") } }
func (server *Server) RegisterFromLua(rcvr *lua.LTable, rcvrFns *lua.LTable) error { logger.Debug("RegisterFromLua") sname := "" rcvr.ForEach(func(key, value lua.LValue) { switch k := key.(type) { case lua.LString: if string(k) == "name" { sname = value.String() } } }) return server.register(rcvr, sname, sname != "", rcvrFns) }
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 Init() { //base var dbCfg config.DBConfig if err := config.ReadConfig("etc/dbBase.json", &dbCfg); err != nil { logger.Fatal("%v", err) } aHosts := make([]string, 0) aHosts = append(aHosts, dbCfg.DBHost) pPollBase = rpc.CreateClientPool(aHosts) if pPollBase == nil { logger.Fatal("create failed") } logger.Debug("Init DBClient : %v ", dbCfg.DBHost) }
func Register_lua_db_DBQuery(L *lua.LState) int { tablename := L.CheckString(1) key := L.CheckString(2) buf := []byte("") exist, err := db.QueryBinary(tablename, key, &buf) if err == nil { L.Push(lua.LString(string(buf))) L.Push(lua.LBool(exist)) L.Push(lua.LString("")) } else { logger.Debug("DBQuery Error %v, %v, %v", buf, exist, err) L.Push(lua.LString("")) L.Push(lua.LBool(exist)) L.Push(lua.LString(err.Error())) } return 3 //value exist err }
func RegisterPbModule(L *lua.LState) int { logger.Debug("pb module Loader") mt := DefaultScript.RegisterGlobalClassBegin(luaIOStringTypeName, &IOString{}) DefaultScript.RegisterGlobalClassFunction(mt, "__create", L.NewFunction(new_iostring)) DefaultScript.RegisterGlobalClassFunction(mt, "__cname", lua.LString(luaIOStringTypeName)) DefaultScript.RegisterGlobalClassFunction(mt, "__ctype", lua.LNumber(1)) DefaultScript.RegisterGlobalClassFunction(mt, "__index", L.SetFuncs(L.NewTable(), indexIOStringMethods)) DefaultScript.RegisterGlobalClassEnd(luaIOStringTypeName) // register functions to the table mod := L.SetFuncs(L.NewTable(), indexPbMethods) // returns the module L.Push(mod) return 1 }
// suitableMethods returns suitable Rpc methods of typ, it will report // error using logger if reportErr is true. func (server *Server) suitableMethods(rcvr interface{}, s *service, typ reflect.Type, reportErr bool, rcvrFns ...interface{}) map[uint32]*methodType { methods := s.method if typ.AssignableTo(reflect.TypeOf((**lua.LTable)(nil)).Elem()) { if len(rcvrFns) > 0 { rcvrFns[0].(*lua.LTable).ForEach(func(key, value lua.LValue) { //logger.Debug("ForEach LTable :%v, %v", key, value) if key.Type() == lua.LTString && value.Type() == lua.LTFunction && value.(*lua.LFunction).Proto.NumParameters == 3 { method, ok := reflect.TypeOf(server).MethodByName("CallLua") if !ok { logger.Debug("regist MethodByName error :%v", key.String()) } mtype := method.Type mname := method.Name // Second arg need not be a pointer. argType := mtype.In(2) if !isExportedOrBuiltinType(argType) { if reportErr { logger.Info("%s argument type not exported: %s", mname, argType) } //continue } methods[server.protocol[key.String()]] = &methodType{method: method, ArgType: argType, luaMethod: value.(*lua.LFunction)} logger.Debug("regist %v", key.String()) } }) } } else { for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) mtype := method.Type mname := method.Name //fmt.Printf("suitableMethods %s, %s, %s, %d \n", mtype, mname, method.PkgPath, mtype.NumIn()) // Method must be exported. if method.PkgPath != "" { continue } // Method needs three ins: receiver, connid, *args. if mtype.NumIn() != 3 { if reportErr { logger.Info("method %s has wrong number of ins: %v", mname, mtype.NumIn()) } continue } idType := mtype.In(1) if !idType.AssignableTo(reflect.TypeOf((*RpcConn)(nil)).Elem()) { if reportErr { logger.Info("%s conn %s must be %s", mname, idType.Name(), reflect.TypeOf((*RpcConn)(nil)).Elem().Name()) } continue } // Second arg need not be a pointer. argType := mtype.In(2) if !isExportedOrBuiltinType(argType) { if reportErr { logger.Info("%s argument type not exported: %s", mname, argType) } continue } // Method needs one out. if mtype.NumOut() != 1 { if reportErr { logger.Info("method %s has wrong number of outs: %v", mname, mtype.NumOut()) } continue } // The return type of the method must be error. if returnType := mtype.Out(0); returnType != typeOfError { if reportErr { logger.Info("method %s returns %s not error", mname, returnType.String()) } continue } methods[server.protocol[mname]] = &methodType{method: method, ArgType: argType} logger.Debug("suitableMethods protocol %v, %d, %v", mname, server.protocol[mname], methods[server.protocol[mname]]) } } return methods }
// ServeConn runs the server on a single connection. // ServeConn blocks, serving the connection until the client hangs up. // The caller typically invokes ServeConn in a go statement. // ServeConn uses the gob wire format (see package gob) on the // connection. To use an alternate codec, use ServeCodec. func (server *Server) ServeConn(conn RpcConn) { id := atomic.AddUint64(&server.id, 1) conn.SetId(id) logger.Debug("ServeConn : %v", id) server.connLock.Lock() server.connMap[id] = conn server.connLock.Unlock() for _, v := range server.onConn { v(conn) } for { server.quitSync.RLock() bQuit := server.quit server.quitSync.RUnlock() if bQuit { break } service, mtype, req, argv, keepReading, err := server.readRequest(conn) if err != nil { if e2, ok := err.(*net.OpError); ok && (e2.Timeout() || e2.Temporary()) { //logger.Info("Read timeout %v", e2) // This will happen frequently continue } if err != io.EOF { logger.Info("rpc: %s", err.Error()) } if !keepReading { break } // send a response if we actually managed to read a header. if req != nil { server.sendErrorResponse(req, conn, err.Error()) server.freeRequest(req) } continue } for _, v := range server.onCallBefore { v(conn) } service.call(server, mtype, req, argv, conn) for _, v := range server.onCallAfter { v(conn) } } for _, v := range server.onDisConn { v(conn) } //conn.Close() server.connLock.Lock() delete(server.connMap, id) server.connLock.Unlock() }
func (self *Connector) CS_CheckSession(conn server.RpcConn, login protobuf.CS_CheckSession) (err error) { rep := protobuf.SC_CheckSessionResult{} uid := login.GetUid() var rst []byte rst, err = redis.Bytes(self.maincache.Do("GET", "SessionKey_"+uid)) rep.SetResult(protobuf.SC_CheckSessionResult_AUTH_FAILED) rep.SetServerTime(uint32(time.Now().Unix())) if rst != nil || err == nil { if login.GetSessionKey() == string(rst) { rep.SetResult(protobuf.SC_CheckSessionResult_OK) } } logger.Debug("SC_CheckSessionResult %v", rep) rep.SetResult(rep.GetResult()) if rep.GetResult() == protobuf.SC_CheckSessionResult_OK { WriteResult(conn, &rep) if p, ok := self.playersbyid[login.GetUid()]; ok { if err := p.conn.Close(); err == nil { logger.Info("kick the online player") } } var base protobuf.PlayerBaseInfo logger.Info("query db : %v", login.GetUid()) result, err := db.Query("playerbase", login.GetUid(), &base) if result == false { base = protobuf.PlayerBaseInfo{} base.SetUid(login.GetUid()) stat := &protobuf.StatusInfo{} stat.SetName("test_" + uid) stat.SetLevel(1) base.SetStat(stat) db.Write("playerbase", login.GetUid(), &base) logger.Info("playerbase create %v", login.GetUid()) } else { if err != nil { logger.Info("err query db : %v", err) return err } logger.Info("playerbase find") } p := &Player{PlayerBaseInfo: &base, conn: conn} p.SetUid(uid) //进入服务器全局表 self.addPlayer(conn.GetId(), p) } else { WriteResult(conn, &rep) go func() { time.Sleep(time.Millisecond * 1000) defer func() { conn.Close() }() }() } return nil }
func (server *Server) register(rcvr interface{}, name string, useName bool, rcvrFns ...interface{}) error { server.mu.Lock() defer server.mu.Unlock() if server.serviceMap == nil { server.serviceMap = make(map[string]*service) } s := new(service) s.typ = reflect.TypeOf(rcvr) s.rcvr = reflect.ValueOf(rcvr) sname := reflect.Indirect(s.rcvr).Type().Name() if useName { sname = name } if sname == "" { log.Fatal("rpc: no service name for type", s.typ.String()) } if !isExported(sname) && !useName { s := "rpc Register: type " + sname + " is not exported" log.Print(s) return errors.New(s) } if _, present := server.serviceMap[sname]; present { return errors.New("rpc: service already defined: " + sname) } s.name = sname s.method = make(map[string]*methodType) // Install the methods if s.typ.AssignableTo(reflect.TypeOf((**lua.LTable)(nil)).Elem()) { if len(rcvrFns) > 0 { rcvrFns[0].(*lua.LTable).ForEach(func(key, value lua.LValue) { //logger.Debug("ForEach LTable :%v, %v", key, value) if key.Type() == lua.LTString && value.Type() == lua.LTFunction && value.(*lua.LFunction).Proto.NumParameters == 3 { method, ok := reflect.TypeOf(server).MethodByName("CallLua") if !ok { logger.Debug("regist MethodByName error :%v", key.String()) } if mt := prepareLuaMethod(method); mt != nil { mt.luaFn = value.(*lua.LFunction) s.method[key.String()] = mt } logger.Debug("regist %v", key.String()) } }) } } else { for m := 0; m < s.typ.NumMethod(); m++ { method := s.typ.Method(m) if mt := prepareMethod(method); mt != nil { s.method[method.Name] = mt } } } if len(s.method) == 0 { s := "rpc Register: type " + sname + " has no exported methods of suitable type" log.Print(s) return errors.New(s) } server.serviceMap[s.name] = s return nil }