├── LICENSE ├── README.md ├── bin ├── config │ ├── db.json │ └── server.json ├── gameserver.exe ├── gameserver.lnk ├── mongodb │ └── data │ │ ├── db │ │ ├── auth.0 │ │ ├── auth.ns │ │ ├── game.0 │ │ ├── game.ns │ │ ├── local.0 │ │ ├── local.ns │ │ ├── mongod.lock │ │ ├── test.0 │ │ └── test.ns │ │ └── log │ │ ├── mongodb.log │ │ ├── mongodb.log.2014-08-05T02-33-11 │ │ ├── mongodb.log.2014-08-05T02-34-46 │ │ ├── mongodb.log.2014-08-05T09-58-40 │ │ ├── mongodb.log.2014-08-05T12-58-18 │ │ ├── mongodb.log.2014-08-06T02-03-26 │ │ ├── mongodb.log.2014-08-06T09-48-43 │ │ ├── mongodb.log.2014-08-06T10-14-49 │ │ ├── mongodb.log.2014-08-07T01-49-38 │ │ ├── mongodb.log.2014-08-07T03-06-53 │ │ ├── mongodb.log.2014-08-07T10-21-28 │ │ ├── mongodb.log.2014-08-08T01-37-40 │ │ ├── mongodb.log.2014-08-08T08-54-46 │ │ ├── mongodb.log.2014-08-08T08-54-59 │ │ ├── mongodb.log.2014-08-11T02-59-54 │ │ ├── mongodb.log.2014-08-11T03-01-30 │ │ ├── mongodb.log.2014-08-11T09-17-37 │ │ ├── mongodb.log.2014-08-12T01-07-51 │ │ └── mongodb.log.2014-08-13T02-01-15 ├── run.bat ├── stop.bat └── tools │ └── protobuf │ ├── error.proto │ ├── frontend.proto │ ├── gate.proto │ ├── msgcmd.proto │ ├── proto_tool.bat │ └── result.proto ├── doc ├── readme │ └── 安装mongodb为windows服务.txt └── 命令 │ └── goprotobuf.txt ├── pkg └── windows_386 │ ├── common.a │ ├── config │ ├── db_config.a │ ├── message_config.a │ └── server_config.a │ ├── framework │ ├── database.a │ ├── network.a │ └── server.a │ ├── gamelogic │ └── rpc.a │ ├── gameserver │ ├── auth │ │ └── app.a │ ├── connector │ │ └── app.a │ ├── database │ │ └── app.a │ ├── game │ │ └── app.a │ ├── gate │ │ └── app.a │ ├── lobby │ │ └── app.a │ ├── master │ │ └── app.a │ └── society │ │ └── app.a │ └── msg_proto.a └── src ├── common ├── common.go ├── json.go ├── node.go ├── pool.go ├── safemap.go ├── safequeue.go ├── safestack.go └── timer.go ├── config ├── db_config │ └── dbconfig.go ├── message_config │ ├── messagecallback.go │ └── messagelist.go └── server_config │ └── serverconfig.go ├── framework ├── database │ └── db.go ├── network │ ├── connchannel.go │ ├── connclient.go │ ├── connection.go │ ├── irpchandler.go │ ├── message.go │ ├── proxymanager.go │ └── session.go └── server │ ├── backend.go │ ├── frontend.go │ ├── iserver.go │ ├── rpcservice.go │ └── server.go ├── gamelogic └── rpc │ └── rpcarg.go ├── gameserver ├── auth │ └── app │ │ ├── auth_app.go │ │ └── auth_rpc.go ├── bin.lnk ├── connector │ └── app │ │ ├── connector_app.go │ │ ├── connector_rpc.go │ │ ├── session_check.go │ │ └── token_manager.go ├── database │ └── app │ │ ├── database_app.go │ │ └── database_rpc.go ├── game │ └── app │ │ ├── game_app.go │ │ └── game_rpc.go ├── gameserver.exe ├── gameserver.go ├── gate │ └── app │ │ ├── gate_app.go │ │ ├── gate_handle.go │ │ └── gate_rpc.go ├── lobby │ └── app │ │ ├── lobby_app.go │ │ └── lobby_rpc.go ├── master │ └── app │ │ ├── master_app.go │ │ └── master_rpc.go └── society │ └── app │ ├── society_app.go │ └── society_rpc.go └── msg_proto ├── error.pb.go ├── frontend.pb.go ├── gate.pb.go ├── msgcmd.pb.go └── result.pb.go /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 gtd138 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LiveServer 2 | LiveServer是一个用Go语言编写的游戏服务器,分布式,采用goprobuf做协议,采用Mongodb做数据库,目前一些便利工具仅用于Windows下。 3 | 使用前请先安装goprotobuf,以及mongodb! 4 | -------------------------------------------------------------------------------- /bin/config/db.json: -------------------------------------------------------------------------------- 1 | { 2 | "config":[ 3 | {"name": "game", "host": "127.0.0.1"}, 4 | {"name": "auth", "host": "127.0.0.1"} 5 | ] 6 | } -------------------------------------------------------------------------------- /bin/config/server.json: -------------------------------------------------------------------------------- 1 | { 2 | "gate": [ 3 | {"id": 1, "type": "gate", "host": "127.0.0.1", "port": "2000", "clientPort": "2001", "frontend": true} 4 | ], 5 | "connector":[ 6 | {"id": 1, "type": "connector", "host": "127.0.0.1", "port": "3000", "clientPort": "3001", "frontend": true} 7 | ], 8 | 9 | "game": [ 10 | {"id": 1, "type": "game", "host": "127.0.0.1", "port": "4000"} 11 | ], 12 | "database": [ 13 | {"id": 1, "type": "database", "host": "127.0.0.1", "port": "5000"} 14 | ], 15 | "society": [ 16 | {"id": 1, "type": "society", "host": "127.0.0.1", "port": "6000"} 17 | ], 18 | "master": [ 19 | {"id": 1, "type": "master", "host": "127.0.0.1", "port": "7000"} 20 | ], 21 | "lobby": [ 22 | {"id": 1, "type": "lobby", "host": "127.0.0.1", "port": "8000"} 23 | ], 24 | "auth": [ 25 | {"id": 1, "type": "auth", "host": "127.0.0.1", "port": "9000"} 26 | ] 27 | } -------------------------------------------------------------------------------- /bin/gameserver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/gameserver.exe -------------------------------------------------------------------------------- /bin/gameserver.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/gameserver.lnk -------------------------------------------------------------------------------- /bin/mongodb/data/db/auth.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/auth.0 -------------------------------------------------------------------------------- /bin/mongodb/data/db/auth.ns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/auth.ns -------------------------------------------------------------------------------- /bin/mongodb/data/db/game.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/game.0 -------------------------------------------------------------------------------- /bin/mongodb/data/db/game.ns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/game.ns -------------------------------------------------------------------------------- /bin/mongodb/data/db/local.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/local.0 -------------------------------------------------------------------------------- /bin/mongodb/data/db/local.ns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/local.ns -------------------------------------------------------------------------------- /bin/mongodb/data/db/mongod.lock: -------------------------------------------------------------------------------- 1 | 2232 2 | -------------------------------------------------------------------------------- /bin/mongodb/data/db/test.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/test.0 -------------------------------------------------------------------------------- /bin/mongodb/data/db/test.ns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/db/test.ns -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-05T02-33-11: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-05T02-33-11 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-05T02-34-46: -------------------------------------------------------------------------------- 1 | 2014-08-05T10:33:11.125+0800 Trying to install Windows service 'LiveServerDB' 2 | 2014-08-05T10:33:11.359+0800 Service 'LiveServerDB' (MongoDB) installed with command line 'E:\MongoDB\bin\mongod.exe --dbpath e:\liveserver\bin\mongodb\data\db --logpath e:\liveserver\bin\mongodb\data\log\mongodb.log --service' 3 | 2014-08-05T10:33:11.359+0800 Service can be started from the command line with 'net start LiveServerDB' 4 | -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-05T09-58-40: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-05T09-58-40 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-05T12-58-18: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-05T12-58-18 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-06T02-03-26: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-06T02-03-26 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-06T09-48-43: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-06T09-48-43 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-06T10-14-49: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-06T10-14-49 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-07T01-49-38: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-07T01-49-38 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-07T03-06-53: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-07T03-06-53 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-07T10-21-28: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-07T10-21-28 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-08T01-37-40: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-08T01-37-40 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-08T08-54-46: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-08T08-54-46 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-08T08-54-59: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-08T08-54-59 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-11T02-59-54: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-11T02-59-54 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-11T03-01-30: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-11T03-01-30 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-11T09-17-37: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-11T09-17-37 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-12T01-07-51: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-12T01-07-51 -------------------------------------------------------------------------------- /bin/mongodb/data/log/mongodb.log.2014-08-13T02-01-15: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/bin/mongodb/data/log/mongodb.log.2014-08-13T02-01-15 -------------------------------------------------------------------------------- /bin/run.bat: -------------------------------------------------------------------------------- 1 | echo off 2 | 3 | taskkill /f /im gameserver.exe 4 | taskkill /f /im gameserver.exe 5 | taskkill /f /im gameserver.exe 6 | taskkill /f /im gameserver.exe 7 | taskkill /f /im gameserver.exe 8 | taskkill /f /im gameserver.exe 9 | taskkill /f /im gameserver.exe 10 | taskkill /f /im gameserver.exe 11 | 12 | start "Lobby 1" C:\Github\LiveServer\bin\gameserver.exe lobby 1 13 | start "Auth 1" C:\Github\LiveServer\bin\gameserver.exe auth 1 14 | start "Master 1" C:\Github\LiveServer\bin\gameserver.exe master 1 15 | start "Gate 1" C:\Github\LiveServer\bin\gameserver.exe gate 1 16 | start "Connector 1" C:\Github\LiveServer\bin\gameserver.exe connector 1 17 | start "Game 1" C:\Github\LiveServer\bin\gameserver.exe game 1 18 | start "DataBase 1" C:\Github\LiveServer\bin\gameserver.exe database 1 19 | start "Society 1" C:\Github\LiveServer\bin\gameserver.exe society 1 -------------------------------------------------------------------------------- /bin/stop.bat: -------------------------------------------------------------------------------- 1 | taskkill /f /im gameserver.exe 2 | taskkill /f /im gameserver.exe 3 | taskkill /f /im gameserver.exe 4 | taskkill /f /im gameserver.exe 5 | taskkill /f /im gameserver.exe 6 | taskkill /f /im gameserver.exe 7 | taskkill /f /im gameserver.exe 8 | taskkill /f /im gameserver.exe -------------------------------------------------------------------------------- /bin/tools/protobuf/error.proto: -------------------------------------------------------------------------------- 1 | // 错误码 2 | package msg_proto; 3 | 4 | enum Error{ 5 | Init_None = -1; // 初始化用 6 | Sucess = 0; // 成功 7 | 8 | // 登录 9 | UnKnow_User = 1; // 不存在用户 10 | Mismatch_Password = 2; // 不匹配的密码 11 | } -------------------------------------------------------------------------------- /bin/tools/protobuf/frontend.proto: -------------------------------------------------------------------------------- 1 | // 前端使用的消息结构 2 | package msg_proto; 3 | 4 | // 用于前端验证的token 5 | message Token { 6 | required string sid = 1; // 会话ID 7 | required string ip = 2; // IP 8 | required string port = 3; // port 9 | required int64 conn_time = 4; // 连接时间 10 | required string pid = 5; // 数据库id,暂定为string 11 | } -------------------------------------------------------------------------------- /bin/tools/protobuf/gate.proto: -------------------------------------------------------------------------------- 1 | // Gate服消息 2 | package msg_proto; 3 | 4 | // 登录请求 5 | message RequestLogin { 6 | required string username = 1; // 用户名 7 | required string password = 2; // 密码 8 | } -------------------------------------------------------------------------------- /bin/tools/protobuf/msgcmd.proto: -------------------------------------------------------------------------------- 1 | // 消息序号 2 | package msg_proto; 3 | 4 | enum MsgCmd { 5 | None = 0; 6 | CmdResult_S = 1; // 错误码 7 | 8 | // 登录 9 | RequestLogin_C = 2; // 请求登录 10 | LoginToken_S = 3; // 登录的验证Token 11 | } -------------------------------------------------------------------------------- /bin/tools/protobuf/proto_tool.bat: -------------------------------------------------------------------------------- 1 | protoc --go_out=. *.proto 2 | 3 | copy *.go ..\..\..\src\msg_proto 4 | del *.go 5 | 6 | pause... -------------------------------------------------------------------------------- /bin/tools/protobuf/result.proto: -------------------------------------------------------------------------------- 1 | // 操作结果 2 | package msg_proto; 3 | import "error.proto"; 4 | 5 | message CmdResult{ 6 | required Error error_code = 1; 7 | } -------------------------------------------------------------------------------- /doc/readme/安装mongodb为windows服务.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/doc/readme/安装mongodb为windows服务.txt -------------------------------------------------------------------------------- /doc/命令/goprotobuf.txt: -------------------------------------------------------------------------------- 1 | protoc --go_out=. *.proto -------------------------------------------------------------------------------- /pkg/windows_386/common.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/common.a -------------------------------------------------------------------------------- /pkg/windows_386/config/db_config.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/config/db_config.a -------------------------------------------------------------------------------- /pkg/windows_386/config/message_config.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/config/message_config.a -------------------------------------------------------------------------------- /pkg/windows_386/config/server_config.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/config/server_config.a -------------------------------------------------------------------------------- /pkg/windows_386/framework/database.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/framework/database.a -------------------------------------------------------------------------------- /pkg/windows_386/framework/network.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/framework/network.a -------------------------------------------------------------------------------- /pkg/windows_386/framework/server.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/framework/server.a -------------------------------------------------------------------------------- /pkg/windows_386/gamelogic/rpc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gamelogic/rpc.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/auth/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/auth/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/connector/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/connector/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/database/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/database/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/game/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/game/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/gate/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/gate/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/lobby/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/lobby/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/master/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/master/app.a -------------------------------------------------------------------------------- /pkg/windows_386/gameserver/society/app.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/gameserver/society/app.a -------------------------------------------------------------------------------- /pkg/windows_386/msg_proto.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/pkg/windows_386/msg_proto.a -------------------------------------------------------------------------------- /src/common/common.go: -------------------------------------------------------------------------------- 1 | // 通用的函数 2 | package common 3 | 4 | import ( 5 | "bytes" 6 | "encoding/gob" 7 | "math" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "time" 12 | ) 13 | 14 | // 获取服务器时间 15 | // @return:返回自1970年1月1日起,到现在的毫秒 16 | func GetTime() int64 { 17 | // 纳秒级别 18 | t1 := time.Now().UnixNano() 19 | // 转成毫秒级别 20 | t2 := float64(t1) / math.Pow(float64(10), float64(6)) 21 | return int64(t2) 22 | } 23 | 24 | // Gob编码 25 | func GobEncode(data interface{}) ([]byte, error) { 26 | buf := bytes.NewBuffer(nil) 27 | enc := gob.NewEncoder(buf) 28 | err := enc.Encode(data) 29 | if err != nil { 30 | return nil, err 31 | } 32 | return buf.Bytes(), nil 33 | } 34 | 35 | // Gob解码 36 | func GobDecode(data []byte, to interface{}) error { 37 | buf := bytes.NewBuffer(data) 38 | dec := gob.NewDecoder(buf) 39 | return dec.Decode(to) 40 | } 41 | 42 | // 查找两个数组的交集、差集 43 | // @note:uint32版本,其中以b为参考数组,查找出a跟b的交集,差集,以及b的新增集合 44 | // same_set为相同集合,rest_set为a多出的集合,new_set为b多出的集合 45 | func FindMixSet(a, b []uint32) (same_set, rest_set, new_set []uint32) { 46 | i := 0 47 | len_a := len(a) 48 | if len_a == 0 { 49 | new_set = b 50 | return 51 | } 52 | if len(b) == 0 { 53 | rest_set = a 54 | return 55 | } 56 | for { 57 | if i > len_a { 58 | break 59 | } 60 | bIn := false 61 | for j := i; j < len(b); j++ { 62 | if b[j] == a[i] { 63 | bIn = true 64 | b[j], b[i] = b[i], b[j] 65 | break 66 | } 67 | } 68 | 69 | if !bIn { 70 | if i >= len_a-1 { 71 | break 72 | } 73 | rest_set = append(rest_set, a[i]) 74 | a[i], a[len_a-1] = a[len_a-1], a[i] 75 | len_a -= 1 76 | } else { 77 | same_set = append(same_set, a[i]) 78 | i++ 79 | } 80 | } 81 | new_index := len(same_set) 82 | if new_index > 0 { 83 | new_set = b[new_index:] 84 | } else { 85 | new_set = b[0:] 86 | } 87 | return 88 | } 89 | 90 | // 获取当前所在exe所在的目录 91 | func GetDir() string { 92 | file, err := exec.LookPath(os.Args[0]) 93 | if err != nil { 94 | println(err) 95 | return "" 96 | } 97 | return filepath.Dir(file) 98 | } 99 | -------------------------------------------------------------------------------- /src/common/json.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | ) 7 | 8 | // 读取Json文件 9 | // file:json文件的完整路径 10 | // conf:config结构实例 11 | func ReadJson(file string, conf interface{}) error { 12 | r, err := os.Open(file) 13 | if err != nil { 14 | println(err) 15 | return err 16 | } 17 | decoder := json.NewDecoder(r) 18 | err = decoder.Decode(conf) 19 | return err 20 | } 21 | -------------------------------------------------------------------------------- /src/common/node.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | // 各种容器的节点 4 | type Node struct { 5 | Elem interface{} 6 | Next *Node 7 | } 8 | -------------------------------------------------------------------------------- /src/common/pool.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | // 对象池实现 4 | 5 | // pool回收物 6 | type IPoolObject interface { 7 | Reset() 8 | } 9 | 10 | type Pool struct { 11 | *Stack 12 | max_size int 13 | } 14 | 15 | func NewPool(size int) *Pool { 16 | return &Pool{ 17 | Stack: NewStack(), 18 | max_size: size, 19 | } 20 | } 21 | 22 | // 从对象池中取出已有对象,没有对象时,需要手动new对象 23 | func (this *Pool) Borrow() (pool_obj IPoolObject, bOk bool) { 24 | bOk = false 25 | if !this.IsEmpty() { 26 | pool_obj = this.Pop().(IPoolObject) 27 | pool_obj.Reset() 28 | bOk = true 29 | } 30 | return 31 | } 32 | 33 | // 归还对象 34 | func (this *Pool) GiveBack(pool_obj IPoolObject) { 35 | if this.Count >= this.max_size { 36 | return 37 | } 38 | this.Push(pool_obj) 39 | } 40 | -------------------------------------------------------------------------------- /src/common/safemap.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | // 注:这里引用BeeGo里面的代码 4 | 5 | import ( 6 | "sync" 7 | ) 8 | 9 | type BeeMapCb func(k, v interface{}) bool 10 | 11 | type BeeMap struct { 12 | lock *sync.RWMutex 13 | bm map[interface{}]interface{} 14 | } 15 | 16 | func NewBeeMap() *BeeMap { 17 | return &BeeMap{ 18 | lock: new(sync.RWMutex), 19 | bm: make(map[interface{}]interface{}), 20 | } 21 | } 22 | 23 | //Get from maps return the k's value 24 | func (m *BeeMap) Get(k interface{}) interface{} { 25 | m.lock.RLock() 26 | defer m.lock.RUnlock() 27 | if val, ok := m.bm[k]; ok { 28 | return val 29 | } 30 | return nil 31 | } 32 | 33 | // Maps the given key and value. Returns false 34 | // if the key is already in the map and changes nothing. 35 | func (m *BeeMap) Set(k interface{}, v interface{}) bool { 36 | m.lock.Lock() 37 | defer m.lock.Unlock() 38 | if val, ok := m.bm[k]; !ok { 39 | m.bm[k] = v 40 | } else if val != v { 41 | m.bm[k] = v 42 | } else { 43 | return false 44 | } 45 | return true 46 | } 47 | 48 | // Returns true if k is exist in the map. 49 | func (m *BeeMap) Check(k interface{}) bool { 50 | m.lock.RLock() 51 | defer m.lock.RUnlock() 52 | if _, ok := m.bm[k]; !ok { 53 | return false 54 | } 55 | return true 56 | } 57 | 58 | func (m *BeeMap) Delete(k interface{}) { 59 | m.lock.Lock() 60 | defer m.lock.Unlock() 61 | delete(m.bm, k) 62 | } 63 | 64 | // 通过回调进行遍历 65 | func (m *BeeMap) Foreach(cb BeeMapCb) { 66 | m.lock.Lock() 67 | defer m.lock.Unlock() 68 | for k, v := range m.bm { 69 | bStop := cb(k, v) 70 | if bStop { 71 | break 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/common/safequeue.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | // 安全队列 8 | type Queue struct { 9 | front, rear *Node // 头尾节点 10 | Count int // 长度 11 | lock *sync.RWMutex // 读写锁 12 | } 13 | 14 | func NewQueue() *Queue { 15 | q := new(Queue) 16 | q.front = new(Node) 17 | q.rear = q.front 18 | q.lock = new(sync.RWMutex) 19 | return q 20 | } 21 | 22 | // 插入队列 23 | func (this *Queue) EnQueue(e interface{}) { 24 | this.lock.Lock() 25 | defer this.lock.Unlock() 26 | q := new(Node) 27 | q.Elem = e 28 | this.rear.Next = q 29 | this.rear = q 30 | this.Count++ 31 | } 32 | 33 | // 出队 34 | func (this *Queue) DeQueue() (e interface{}) { 35 | this.lock.Lock() 36 | defer this.lock.Unlock() 37 | if this.IsEmpty() { 38 | return 39 | } 40 | q := this.front.Next 41 | e = q.Elem 42 | if this.front.Next == this.rear { 43 | this.rear = this.front 44 | } 45 | this.front.Next = q.Next 46 | this.Count-- 47 | return 48 | } 49 | 50 | // 全部出队 51 | func (this *Queue) DeQueueAll() (es []interface{}) { 52 | this.lock.Lock() 53 | defer this.lock.Unlock() 54 | for { 55 | if this.IsEmpty() { 56 | break 57 | } 58 | q := this.front.Next 59 | e := q.Elem 60 | if this.front.Next == this.rear { 61 | this.rear = this.front 62 | } 63 | this.front.Next = q.Next 64 | this.Count-- 65 | es = append(es, e) 66 | } 67 | return 68 | } 69 | 70 | // 是否为空 71 | func (this *Queue) IsEmpty() bool { 72 | this.lock.RLock() 73 | defer this.lock.RUnlock() 74 | return (this.front == this.rear) 75 | } 76 | 77 | // 获取队头 78 | func (this *Queue) TopQueue() (e interface{}) { 79 | this.lock.RLock() 80 | defer this.lock.RUnlock() 81 | if this.IsEmpty() { 82 | return 83 | } 84 | return this.front.Next.Elem 85 | } 86 | 87 | // 清空 88 | func (this *Queue) Clear() { 89 | this.lock.Lock() 90 | defer this.lock.Unlock() 91 | this.front.Next = nil 92 | this.rear = this.front 93 | } 94 | -------------------------------------------------------------------------------- /src/common/safestack.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | // 安全栈 8 | type Stack struct { 9 | lock *sync.RWMutex // 锁 10 | top *Node // 栈顶 11 | Count int // 栈计数 12 | } 13 | 14 | func NewStack() *Stack { 15 | return &Stack{ 16 | lock: new(sync.RWMutex), 17 | } 18 | } 19 | 20 | func (this *Stack) Push(elem interface{}) { 21 | this.lock.Lock() 22 | defer this.lock.Unlock() 23 | n := new(Node) 24 | n.Elem = elem 25 | n.Next = this.top 26 | this.top = n 27 | this.Count++ 28 | } 29 | 30 | func (this *Stack) Pop() (elem interface{}) { 31 | this.lock.Lock() 32 | defer this.lock.Unlock() 33 | if this.IsEmpty() { 34 | println("栈为空") 35 | return 36 | } 37 | n := this.top 38 | elem = n.Elem 39 | this.top = n.Next 40 | this.Count-- 41 | return 42 | } 43 | 44 | func (this *Stack) IsEmpty() bool { 45 | this.lock.RLock() 46 | defer this.lock.RUnlock() 47 | return (this.top == nil) 48 | } 49 | 50 | func (this *Stack) StackTop() (elem interface{}) { 51 | this.lock.RLock() 52 | defer this.lock.RUnlock() 53 | if this.IsEmpty() { 54 | println("栈为空") 55 | return 56 | } 57 | elem = this.top.Elem 58 | return 59 | } 60 | 61 | func (this *Stack) PopAll() (elems []interface{}) { 62 | this.lock.Lock() 63 | defer this.lock.Unlock() 64 | for { 65 | if this.top == nil { 66 | break 67 | } 68 | n := this.top 69 | e := n.Elem 70 | this.top = n.Next 71 | elems = append(elems, e) 72 | this.Count-- 73 | } 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /src/common/timer.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "time" 4 | 5 | // 返回值用于停止定时器,返回false停止定时器 6 | type TimerCallBack func(*Timer, ...interface{}) bool 7 | 8 | type Timer struct { 9 | *time.Ticker // Tiker 10 | interval time.Duration // 触发间隔 11 | bSync bool // 是否在goroutine中运行 12 | bStop bool // 定时器停止标志位 13 | callback TimerCallBack // 回调 14 | args []interface{} // 回调的参数 15 | MaxCount int // 最大触发次数 16 | Count int // 当前触发次数 17 | } 18 | 19 | // 定时器 20 | // interval:时间间隔以time.Nanosecond为单位 21 | // count:触发最大次数,其中0为无限触发 22 | // bSync:是否同步执行,是:则创建goroutine执行,否:会阻塞当前goroutine 23 | // fun:触发回调 24 | // args:回调传进的参数 25 | func NewTimer(interval time.Duration, count int, bSync bool, fun TimerCallBack, args ...interface{}) *Timer { 26 | return &Timer{ 27 | interval: interval, 28 | bSync: bSync, 29 | callback: fun, 30 | args: args, 31 | MaxCount: count, 32 | } 33 | } 34 | 35 | // 启动定时器 36 | func (this *Timer) Start() { 37 | if this.bSync { 38 | go this.tick() 39 | } else { 40 | this.tick() 41 | } 42 | } 43 | 44 | // 停止定时器 45 | func (this *Timer) Stop() { 46 | this.bStop = true 47 | } 48 | 49 | // 判断是否要停止 50 | func (this *Timer) isStop() bool { 51 | if this.bStop { 52 | return true 53 | } 54 | 55 | // 达到最大计数,则停止 56 | if this.MaxCount <= 0 { 57 | return false 58 | } else { 59 | this.Count++ 60 | if this.Count >= this.MaxCount { 61 | return true 62 | } 63 | } 64 | 65 | return false 66 | } 67 | 68 | // 定时器循环 69 | func (this *Timer) tick() { 70 | this.Ticker = time.NewTicker(this.interval) 71 | this.bStop = false 72 | TICK: 73 | for { 74 | select { 75 | case <-this.Ticker.C: 76 | if this.isStop() { 77 | break TICK 78 | } 79 | this.bStop = !this.callback(this, this.args...) 80 | } 81 | } 82 | this.Ticker.Stop() 83 | } 84 | -------------------------------------------------------------------------------- /src/config/db_config/dbconfig.go: -------------------------------------------------------------------------------- 1 | package dbconfig 2 | 3 | // 配置元素 4 | type DBConfigElem struct { 5 | Name string // 数据库名 6 | Host string // 数据库地址 7 | } 8 | 9 | // 数据库配置 10 | type DBConfig struct { 11 | Config []DBConfigElem 12 | } 13 | 14 | func (this *DBConfig) GetConfig(name string) (config DBConfigElem) { 15 | for _, v := range this.Config { 16 | if name == v.Name { 17 | config = v 18 | break 19 | } 20 | } 21 | return 22 | } 23 | -------------------------------------------------------------------------------- /src/config/message_config/messagecallback.go: -------------------------------------------------------------------------------- 1 | package msg_conf 2 | 3 | import ( 4 | // "code.google.com/p/goprotobuf/proto" 5 | . "msg_proto" 6 | 7 | "github.com/golang/protobuf/proto" 8 | ) 9 | 10 | // 单件 11 | var instance *messageCallback 12 | 13 | // 消息处理函数 14 | type MessageHandleFunc func(sid string, message proto.Message) 15 | 16 | type messageCallback struct { 17 | funcMap map[MsgCmd]MessageHandleFunc // 消息请求回调 18 | } 19 | 20 | // 获取消息回调单件 21 | func MessageCallback() *messageCallback { 22 | if instance == nil { 23 | instance = &messageCallback{ 24 | funcMap: make(map[MsgCmd]MessageHandleFunc), 25 | } 26 | } 27 | return instance 28 | } 29 | 30 | func (this *messageCallback) Register(msg_handle MsgCmd, fun MessageHandleFunc) { 31 | if _, bOk := this.funcMap[msg_handle]; bOk { 32 | println("重复注册消息回调!") 33 | return 34 | } 35 | this.funcMap[msg_handle] = fun 36 | } 37 | 38 | // 回调消息 39 | func (this *messageCallback) Handle(msg_handle MsgCmd, sid string, message proto.Message) { 40 | if _, bOk := this.funcMap[msg_handle]; !bOk { 41 | println("不存在此消息回调") 42 | return 43 | } 44 | this.funcMap[msg_handle](sid, message) 45 | } 46 | -------------------------------------------------------------------------------- /src/config/message_config/messagelist.go: -------------------------------------------------------------------------------- 1 | package msg_conf 2 | 3 | import ( 4 | //"code.google.com/p/goprotobuf/proto" 5 | . "msg_proto" 6 | 7 | "github.com/golang/protobuf/proto" 8 | ) 9 | 10 | // 消息定义 11 | type MsgDef struct { 12 | ServerType string // 发送的服务器类型,客户端的则为"client" 13 | MsgObj proto.Message // 消息原型 14 | } 15 | 16 | var MessageMap map[MsgCmd]MsgDef 17 | 18 | // 获取消息对应的服务器类型 19 | func GetMsgServerType(msg_id MsgCmd) (server_type string, bOk bool) { 20 | msg_obj, ok := MessageMap[msg_id] 21 | bOk = ok 22 | if !ok { 23 | return 24 | } 25 | server_type = msg_obj.ServerType 26 | return 27 | } 28 | 29 | // 注册消息 30 | func RegisterMsg() { 31 | MessageMap = make(map[MsgCmd]MsgDef) 32 | 33 | // 以下为消息注册表 34 | // 服务器结果 35 | MessageMap[MsgCmd_CmdResult_S] = MsgDef{"client", &CmdResult{}} 36 | MessageMap[MsgCmd_LoginToken_S] = MsgDef{"client", &Token{}} 37 | 38 | // 客户端请求 39 | MessageMap[MsgCmd_RequestLogin_C] = MsgDef{"gate", &RequestLogin{}} 40 | } 41 | -------------------------------------------------------------------------------- /src/config/server_config/serverconfig.go: -------------------------------------------------------------------------------- 1 | package server_conf 2 | 3 | // 单件 4 | var instance *ServerConfig 5 | var bReadConfig bool 6 | 7 | // 服务器配置元素 8 | type ConfigElem struct { 9 | Id int // 服务器id 10 | Type string // 类型 11 | Host string // 地址 12 | Port string // rpc端口 13 | ClientPort string // 客户端端口 14 | Fronted bool // 是否为前端 15 | } 16 | 17 | // 服务器配置 18 | type ServerConfig struct { 19 | // 前端服务器 20 | Gate []ConfigElem // 网关服 21 | Connector []ConfigElem // 连接服 22 | 23 | // 后端服务器 24 | Master []ConfigElem // 中心管理服 25 | Game []ConfigElem // 游戏逻辑服 26 | DataBase []ConfigElem // 数据库缓存服 27 | Society []ConfigElem // 社会服 28 | Lobby []ConfigElem // 大厅服 29 | Auth []ConfigElem // 第三方验证服 30 | 31 | ConfigMap map[string][]ConfigElem // 配置map 32 | } 33 | 34 | func (this *ServerConfig) ConvertToMap() { 35 | if this.ConfigMap != nil { 36 | return 37 | } 38 | this.ConfigMap = make(map[string][]ConfigElem) 39 | this.ConfigMap["gate"] = this.Gate 40 | this.ConfigMap["connector"] = this.Connector 41 | this.ConfigMap["master"] = this.Master 42 | this.ConfigMap["game"] = this.Game 43 | this.ConfigMap["database"] = this.DataBase 44 | this.ConfigMap["society"] = this.Society 45 | this.ConfigMap["lobby"] = this.Lobby 46 | this.ConfigMap["auth"] = this.Auth 47 | } 48 | 49 | // 获取服务器配置 50 | func (this *ServerConfig) GetConfig(server_type string, server_id int) (conf *ConfigElem) { 51 | conf_list, bok := this.ConfigMap[server_type] 52 | if !bok { 53 | return 54 | } 55 | for i, v := range conf_list { 56 | if v.Id == server_id { 57 | conf = &(conf_list[i]) 58 | break 59 | } 60 | } 61 | return 62 | } 63 | 64 | func GetSingleton() *ServerConfig { 65 | if instance == nil { 66 | instance = new(ServerConfig) 67 | } 68 | return instance 69 | } 70 | 71 | func IsReadConfig() bool { 72 | return bReadConfig 73 | } 74 | 75 | func ReadConfig(bread bool) { 76 | bReadConfig = bread 77 | } 78 | -------------------------------------------------------------------------------- /src/framework/database/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "common" 5 | . "config/db_config" 6 | "log" 7 | "os" 8 | "strings" 9 | "time" 10 | 11 | "gopkg.in/mgo.v2" 12 | "gopkg.in/mgo.v2/bson" 13 | ) 14 | 15 | const ( 16 | DBPATH = "LiveServer\\bin\\config\\db.json" 17 | DB_DIR = "liveserver" 18 | 19 | DURTIME = 5 // 重连间隔5s 20 | RETRY_TIME = 10 // 重连10次 21 | 22 | DB_PROCESS_DURTIME = 15 // 数据库操作处理为15分钟一次 23 | ) 24 | 25 | // 数据队列元素 26 | type DBQueueElem struct { 27 | Table string // 表名 28 | Id_ bson.ObjectId `bson:"_id"` // 数据ID 29 | Data interface{} // 数据 30 | } 31 | 32 | type DBInitFinCallback func() 33 | 34 | // 数据库模块 35 | type DB struct { 36 | *DBConfig // 数据库配置 37 | *mgo.Session // 数据会话 38 | *mgo.Database // 连接的数据库 39 | insertQueue *common.Queue // 插入数据队列 40 | fixQueue *common.Queue // 修改数据队列 41 | delQueue *common.Queue // 删除数据队列 42 | retryTimer *common.Timer // 重连定时器 43 | processTimer *common.Timer // 数据库操作定时器 44 | 45 | // 数据库的一些属性 46 | Host string // 数据库地址 47 | Name string // 数据库名 48 | 49 | // 回调 50 | InitCallback DBInitFinCallback // 初始化结束回调 51 | } 52 | 53 | func NewDB(name string) *DB { 54 | return &DB{ 55 | DBConfig: &DBConfig{}, 56 | insertQueue: common.NewQueue(), 57 | fixQueue: common.NewQueue(), 58 | delQueue: common.NewQueue(), 59 | Name: name, 60 | } 61 | } 62 | 63 | // 初始化数据库,请用goroutine 64 | func (this *DB) Init() { 65 | this.loadDBConfig() 66 | this.connectDB() 67 | this.setupDB() 68 | if this.InitCallback != nil { 69 | this.InitCallback() 70 | } 71 | } 72 | 73 | // 读取配置文件 74 | func (this *DB) loadDBConfig() { 75 | conf_dir := common.GetDir() 76 | if conf_dir == "" { 77 | println("读数据库配置文件失败!") 78 | os.Exit(1) 79 | } 80 | conf_slice := strings.Split(conf_dir, "\\") 81 | var index int = -1 82 | for i, v := range conf_slice { 83 | if strings.ToLower(v) == DB_DIR { 84 | index = i 85 | break 86 | } 87 | } 88 | if index == -1 { 89 | println("请把服务器拷贝到liveserver下,读取数据库配置文件失败!") 90 | os.Exit(1) 91 | } 92 | var conf_path string 93 | for i := 0; i < index; i++ { 94 | conf_path += conf_slice[i] + "\\" 95 | } 96 | conf_path += DBPATH 97 | common.ReadJson(conf_path, this.DBConfig) 98 | } 99 | 100 | // 连接数据库 101 | func (this *DB) connectDB() { 102 | this.Host = this.GetConfig(this.Name).Host 103 | // 开启goroutine进行连接数据库 104 | this.retryTimer = common.NewTimer(time.Second*DURTIME, 0, false, this.retry) 105 | log.Println("开始连接数据库...") 106 | this.retryTimer.Start() 107 | } 108 | 109 | // 重连DB 110 | func (this *DB) retry(t *common.Timer, args ...interface{}) bool { 111 | var err error 112 | this.Session, err = mgo.Dial(this.Host) 113 | t.Count = t.Count + 1 114 | log.Println("连接数据库次数 = ", t.Count) 115 | if err != nil { 116 | if t.Count >= RETRY_TIME { 117 | log.Println("连接数据库次数过多,连接数据库失败!") 118 | return false 119 | } 120 | return true 121 | } 122 | log.Println("连接数据库成功!") 123 | return false 124 | } 125 | 126 | // 设置DB 127 | func (this *DB) setupDB() { 128 | this.Session.SetMode(mgo.Monotonic, true) 129 | this.Database = this.Session.DB(this.Name) 130 | // 通过定时器驱动数据模块 131 | this.processTimer = common.NewTimer(time.Minute*DB_PROCESS_DURTIME, 0, true, this.process) 132 | this.processTimer.Start() 133 | } 134 | 135 | // 更改使用的数据库(IP相同) 136 | func (this *DB) ChangeDB(db_name string) { 137 | this.Database = this.Session.DB(db_name) 138 | } 139 | 140 | // 获取数据库某张表所有数值 141 | // table:表名 142 | // result:数据结构 143 | func (this *DB) FindAll(table string, result interface{}) (err error) { 144 | err = this.Database.C(table).Find(&bson.M{}).All(result) 145 | return 146 | } 147 | 148 | // note:以下操作,不会马上进行实际的数据库操作 149 | // 插入数据 150 | func (this *DB) Insert(table string, data interface{}) { 151 | e := &DBQueueElem{ 152 | Table: table, 153 | Data: data, 154 | } 155 | this.insertQueue.EnQueue(e) 156 | } 157 | 158 | // 更新数据 159 | func (this *DB) Update(table string, id bson.ObjectId, data interface{}) { 160 | e := &DBQueueElem{ 161 | Table: table, 162 | Id_: id, 163 | Data: data, 164 | } 165 | this.fixQueue.EnQueue(e) 166 | } 167 | 168 | // 删除数据 169 | func (this *DB) Remove(table string, id bson.ObjectId) { 170 | e := &DBQueueElem{ 171 | Table: table, 172 | Id_: id, 173 | } 174 | this.delQueue.EnQueue(e) 175 | } 176 | 177 | // 以下为实际进行数据操作 178 | func (this *DB) process(t *common.Timer, args ...interface{}) bool { 179 | // 插入 180 | q := this.insertQueue.DeQueueAll() 181 | for i := 0; i < len(q); i++ { 182 | e := q[i].(*DBQueueElem) 183 | this.Database.C(e.Table).Insert(e.Data) 184 | } 185 | // 修改 186 | q = q[:0] 187 | q = this.fixQueue.DeQueueAll() 188 | for i := 0; i < len(q); i++ { 189 | e := q[i].(*DBQueueElem) 190 | this.Database.C(e.Table).Update(bson.M{"_id": bson.ObjectIdHex(e.Id_.Hex())}, e.Data) 191 | } 192 | // 删除 193 | q = q[:0] 194 | q = this.delQueue.DeQueueAll() 195 | for i := 0; i < len(q); i++ { 196 | e := q[i].(*DBQueueElem) 197 | this.Database.C(e.Table).Remove(bson.M{"_id": bson.ObjectIdHex(e.Id_.Hex())}) 198 | } 199 | return true 200 | } 201 | -------------------------------------------------------------------------------- /src/framework/network/connchannel.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "common" 5 | "net" 6 | "sync" 7 | ) 8 | 9 | // 连接通道 10 | type ConnChannel struct { 11 | conn net.Conn // 连接 12 | //rev_chan *common.Queue // 接收通道 13 | send_chan *common.Queue // 发送通道 14 | bclosed bool // 是否要关闭 15 | slock *sync.RWMutex // 状态锁 16 | } 17 | 18 | func NewConnChannel(conn net.Conn) *ConnChannel { 19 | return &ConnChannel{ 20 | conn: conn, 21 | bclosed: true, 22 | //rev_chan: common.NewQueue(), 23 | send_chan: common.NewQueue(), 24 | slock: new(sync.RWMutex), 25 | } 26 | } 27 | 28 | func (this *ConnChannel) Reset() { 29 | this.conn = nil 30 | //this.rev_chan.Clear() 31 | this.send_chan.Clear() 32 | this.bclosed = false 33 | } 34 | 35 | // 写字节 36 | func (this *ConnChannel) WriteBytes(bytes []byte) { 37 | this.send_chan.EnQueue(bytes) 38 | } 39 | 40 | // 读取字节 41 | func (this *ConnChannel) ReadBytes() [][]byte { 42 | var bytes [][]byte 43 | r := this.send_chan.DeQueueAll() 44 | for i := 0; i < len(r); i++ { 45 | bytes = append(bytes, r[i].([]byte)) 46 | } 47 | this.send_chan.Clear() 48 | return bytes 49 | } 50 | 51 | // 设置通道是否关闭 52 | func (this *ConnChannel) SetClose(bclose bool) { 53 | this.slock.Lock() 54 | defer this.slock.Unlock() 55 | this.bclosed = bclose 56 | } 57 | 58 | // 指出通道是否关闭 59 | func (this *ConnChannel) IsClose() (bclose bool) { 60 | this.slock.RLock() 61 | defer this.slock.RUnlock() 62 | bclose = this.bclosed 63 | return 64 | } 65 | 66 | // 获取连接 67 | func (this *ConnChannel) GetConn() net.Conn { 68 | return this.conn 69 | } 70 | 71 | // 真正写消息 72 | func (this *ConnChannel) ConnWrite() { 73 | bytes := this.ReadBytes() 74 | for _, v := range bytes { 75 | this.conn.Write(v) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/framework/network/connclient.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "net/rpc" 5 | "sync" 6 | ) 7 | 8 | type ConnClient struct { 9 | *rpc.Client // rpc客户端 10 | connServerType string // 连接的服务端类型名 11 | connServerID int // 连接的服务器ID 12 | rpcRequestChannel []*MessageObject // rpc请求通道 13 | lock *sync.RWMutex // 读取请求锁 14 | } 15 | 16 | func NewConnClient(server_type string, server_id int) *ConnClient { 17 | return &ConnClient{ 18 | //Client: client, 19 | connServerType: server_type, 20 | connServerID: server_id, 21 | lock: new(sync.RWMutex), 22 | } 23 | } 24 | 25 | // 放置请求 26 | func (this *ConnClient) PushRequest(request *MessageObject) { 27 | this.lock.Lock() 28 | defer this.lock.Unlock() 29 | this.rpcRequestChannel = append(this.rpcRequestChannel, request) 30 | } 31 | 32 | // 把所有请求发送到远程服务器 33 | func (this *ConnClient) RemoteCall(funcname string) { 34 | this.lock.Lock() 35 | defer this.lock.Unlock() 36 | request_channel := this.rpcRequestChannel[0:] 37 | var bOk bool 38 | go this.Client.Call(funcname, request_channel, &bOk) 39 | } 40 | 41 | // 获取远程服务器类型 42 | func (this *ConnClient) GetRemoteServerType() string { 43 | return this.connServerType 44 | } 45 | 46 | // 获取远程服务器ID 47 | func (this *ConnClient) GetRemoteServerID() int { 48 | return this.connServerID 49 | } 50 | -------------------------------------------------------------------------------- /src/framework/network/connection.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | // 连接组件 4 | import ( 5 | "common" 6 | "log" 7 | "net" 8 | "net/rpc" 9 | "sync" 10 | "time" 11 | ) 12 | 13 | const ( 14 | MAX_CONN_BUFF = 4096 15 | RPC_RETRY_INTERVAL = 5 // rpc重连间隔,单位秒 16 | RPC_RETRY_TIME = 10 // rpc重连次数 17 | ) 18 | 19 | // 监听回调,用于接收新连接 20 | type ConnectionListenerCallback func(conn net.Conn) 21 | type TCPRequestCallback func(net.Conn, [][]byte) 22 | 23 | type Connection struct { 24 | *common.Pool // 连接通道池 25 | connChanList []*ConnChannel // 连接通道列表 26 | buildChannelLock *sync.RWMutex // 创建通道锁 27 | listenerMap map[string]*net.TCPListener // TCP监听,map[标识]listener 28 | tcpListenerCB ConnectionListenerCallback // TCP监听回调 29 | tcpRequestCB TCPRequestCallback // tcp请求处理回调 30 | rpcClientMap []*ConnClient // 连接远程服务器的客户端 31 | } 32 | 33 | func NewConnection() *Connection { 34 | return &Connection{ 35 | Pool: common.NewPool(MAX_SESSION), 36 | buildChannelLock: new(sync.RWMutex), 37 | listenerMap: make(map[string]*net.TCPListener), 38 | } 39 | } 40 | 41 | // 创建网络监听,使用TCP协议 42 | func (this *Connection) CreateTCPListener(addr, port string) *net.TCPListener { 43 | tcpAddr, err := net.ResolveTCPAddr("tcp", addr+":"+port) 44 | if err != nil { 45 | println("创建监听失败!(1)") 46 | return nil 47 | } 48 | listener, err := net.ListenTCP("tcp", tcpAddr) 49 | if err != nil { 50 | println("创建监听失败!(2)") 51 | return nil 52 | } 53 | return listener 54 | } 55 | 56 | // 添加监听 57 | func (this *Connection) AddListener(label string, listener *net.TCPListener) bool { 58 | _, bOk := this.listenerMap[label] 59 | if bOk { 60 | return !bOk 61 | } 62 | this.listenerMap[label] = listener 63 | return bOk 64 | } 65 | 66 | // 启动Tcp监听 67 | func (this *Connection) RunTCPListen(listener net.Listener) { 68 | for { 69 | conn, err := listener.Accept() 70 | if err != nil { 71 | println(err) 72 | continue 73 | } 74 | if this.tcpListenerCB == nil { 75 | continue 76 | } 77 | // 开goroutine处理监听回调 78 | go this.tcpListenerCB(conn) 79 | } 80 | } 81 | 82 | // 启动RPC监听 83 | func (this *Connection) RunRPCListen(listener net.Listener) { 84 | for { 85 | conn, err := listener.Accept() 86 | if err != nil { 87 | continue 88 | } 89 | go rpc.ServeConn(conn) 90 | } 91 | } 92 | 93 | // 添加TCP监听回调 94 | func (this *Connection) AddTCPListenerCallback(cb ConnectionListenerCallback) { 95 | this.tcpListenerCB = cb 96 | } 97 | 98 | // 添加TCP请求回调 99 | func (this *Connection) AddTCPRequestCallback(cb TCPRequestCallback) { 100 | this.tcpRequestCB = cb 101 | } 102 | 103 | // 设置连接通道 104 | func (this *Connection) SetupConnChannel(conn net.Conn) { 105 | this.connChanList = append(this.connChanList, NewConnChannel(conn)) 106 | } 107 | 108 | // 建立RPC连接 109 | // 最后一个参数为重试连接,默认5s连接一次 110 | func (this *Connection) ConnectRPCServer(addr, port, server_type string, server_id int) { 111 | fullAddr := addr + ":" + port 112 | conn_client := NewConnClient(server_type, server_id) 113 | timer := *common.NewTimer(time.Second*RPC_RETRY_INTERVAL, 0, false, this.startConnectRemoteServer, conn_client, fullAddr) 114 | log.Println("开始连接远程服务器 server = ", server_type, ", id =", server_id) 115 | timer.Start() 116 | } 117 | 118 | // 重连服务器 119 | func (this *Connection) startConnectRemoteServer(t *common.Timer, arg ...interface{}) bool { 120 | t.Count = t.Count + 1 121 | log.Println("尝试连接次数 = ", t.Count) 122 | if len(arg) <= 0 { 123 | return false 124 | } 125 | client := arg[0].(*ConnClient) 126 | fullAddr := arg[1].(string) 127 | var err error 128 | client.Client, err = rpc.Dial("tcp", fullAddr) 129 | if err == nil { 130 | this.rpcClientMap = append(this.rpcClientMap, client) 131 | log.Println("连接成功, server = ", client.connServerType, ", id =", client.connServerID) 132 | return false 133 | } else { 134 | if t.Count >= RPC_RETRY_TIME { 135 | log.Println("连接数达到最大值,断开连接...") 136 | return false 137 | } 138 | } 139 | return (err != nil) 140 | } 141 | 142 | // 创建连接通道 143 | func (this *Connection) BuildConnChannel(conn net.Conn) *ConnChannel { 144 | this.buildChannelLock.Lock() 145 | defer this.buildChannelLock.Unlock() 146 | obj, bOk := this.Borrow() 147 | var channel *ConnChannel 148 | if !bOk { 149 | channel = NewConnChannel(conn) 150 | } else { 151 | obj.Reset() 152 | channel = obj.(*ConnChannel) 153 | } 154 | this.connChanList = append(this.connChanList, channel) 155 | return channel 156 | } 157 | 158 | // 销毁连接通道 159 | func (this *Connection) DestoryConnChannel(conn net.Conn) { 160 | this.buildChannelLock.Lock() 161 | defer this.buildChannelLock.Unlock() 162 | var index int 163 | for i := range this.connChanList { 164 | if this.connChanList[i].conn == conn { 165 | index = i 166 | break 167 | } 168 | } 169 | channel := this.connChanList[index] 170 | this.connChanList = append(this.connChanList[0:index], this.connChanList[index+1:]...) 171 | channel.conn.Close() 172 | this.GiveBack(channel) 173 | } 174 | 175 | // 关闭连接 176 | func (this *Connection) CloseConnChannel(conn net.Conn) { 177 | this.buildChannelLock.Lock() 178 | defer this.buildChannelLock.Unlock() 179 | for i := range this.connChanList { 180 | if this.connChanList[i].conn == conn { 181 | this.connChanList[i].SetClose(true) 182 | break 183 | } 184 | } 185 | } 186 | 187 | // 接收连接请求 188 | func (this *Connection) AcceptTCPConnRequest(conn_chan *ConnChannel) { 189 | println("接收连接请求......") 190 | defer this.DestoryConnChannel(conn_chan.conn) 191 | var request []byte 192 | for { 193 | // 通道关闭则关闭连接 194 | if conn_chan.IsClose() { 195 | break 196 | } 197 | 198 | request = make([]byte, MAX_CONN_BUFF) 199 | length, err := conn_chan.conn.Read(request) 200 | if err != nil { 201 | println(err) 202 | continue 203 | } 204 | 205 | if length <= 0 { 206 | continue 207 | } 208 | 209 | // 把消息添加到相关队列 210 | clip := this.cutConnRequest(request) 211 | if len(clip) <= 0 { 212 | continue 213 | } 214 | // 处理请求 215 | this.tcpRequestCB(conn_chan.conn, clip) 216 | } 217 | } 218 | 219 | // 剪切请求数组 220 | func (this *Connection) cutConnRequest(request []byte) (clip_reuqest [][]byte) { 221 | request_len := len(request) 222 | if request_len <= 0 { 223 | println("请求长度为0!") 224 | return 225 | } 226 | for { 227 | request_len = len(request) 228 | if request_len <= 0 { 229 | break 230 | } 231 | // 请求头一般为消息长度 232 | req_head := request[0] 233 | if int(req_head) > request_len { 234 | println("消息实际长度过短,可能被截断!") 235 | break 236 | } 237 | cut := request[:req_head] 238 | clip_reuqest = append(clip_reuqest, cut) 239 | request = request[req_head:] 240 | } 241 | return 242 | } 243 | 244 | // 获取通道 245 | func (this *Connection) GetAllConnChannel() []*ConnChannel { 246 | return this.connChanList 247 | } 248 | 249 | // 获取通道锁 250 | func (this *Connection) GetChannelLock() *sync.RWMutex { 251 | return this.buildChannelLock 252 | } 253 | 254 | // 查找rpc端 255 | func (this *Connection) FindRPCClient(server_type string) (client_list []*ConnClient) { 256 | for i, v := range this.rpcClientMap { 257 | if v.connServerType == server_type { 258 | client_list = append(client_list, this.rpcClientMap[i]) 259 | } 260 | } 261 | return 262 | } 263 | 264 | // 获取rpc客户端列表 265 | func (this *Connection) GetRPCClients() []*ConnClient { 266 | return this.rpcClientMap 267 | } 268 | 269 | // 获取rpc客户端列表,通过名称以及id 270 | // id:为小于0时,默认返回跟其类型一致的端 271 | func (this *Connection) FindPRCClientsByDetail(server_type string, id int) (clients []*ConnClient) { 272 | list := this.FindRPCClient(server_type) 273 | if id > 0 { 274 | for i := 0; i < len(list); i++ { 275 | if list[i].connServerID == id { 276 | clients = append(clients, list[i]) 277 | } 278 | } 279 | } else { 280 | clients = list 281 | } 282 | return 283 | } 284 | -------------------------------------------------------------------------------- /src/framework/network/irpchandler.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | // 用于处于RPC调用 4 | type IRPCHandler interface { 5 | RouteMessage([]*MessageObject, *bool) error 6 | } 7 | -------------------------------------------------------------------------------- /src/framework/network/message.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | // 消息模块 4 | import ( 5 | // "code.google.com/p/goprotobuf/proto" 6 | "common" 7 | "config/message_config" 8 | "math" 9 | "msg_proto" 10 | 11 | "github.com/golang/protobuf/proto" 12 | //"reflect" 13 | ) 14 | 15 | const ( 16 | SEND_MSG = iota 17 | REV_MSG 18 | ) 19 | 20 | type ByteMessage []byte 21 | 22 | // 消息实体 23 | type MessageObject struct { 24 | Sid string // 对应的会话ID 25 | ID msg_proto.MsgCmd // 消息编号 26 | IsBc bool // 是否为广播消息 27 | Byte_Msg_body ByteMessage // Byte消息体 28 | Proto_Msg_body proto.Message // proto消息体 29 | } 30 | 31 | func (this *MessageObject) Reset() { 32 | this.Sid = "" 33 | this.ID = msg_proto.MsgCmd_None 34 | this.Byte_Msg_body = this.Byte_Msg_body[:0] 35 | this.Proto_Msg_body.Reset() 36 | } 37 | 38 | // 消息管理器 39 | type MessageManager struct { 40 | //msgRegistry *common.BeeMap //消息原型注册表,map[name]Message 41 | //msgIDMap *common.BeeMap // 消息ID与名字映射表,map[name]id 42 | sendChannel *common.Queue // 发消息通道 43 | revChannel *common.Queue // 接收到消息通道 44 | } 45 | 46 | func NewMessageManager() *MessageManager { 47 | msgMgr := &MessageManager{ 48 | //msgRegistry: common.NewBeeMap(), 49 | //msgIDMap: common.NewBeeMap(), 50 | sendChannel: common.NewQueue(), 51 | revChannel: common.NewQueue(), 52 | } 53 | //msgMgr.RegisterAllMessage() 54 | // 注册所有消息 55 | msg_conf.RegisterMsg() 56 | return msgMgr 57 | } 58 | 59 | // 消息通道操作 60 | func (this *MessageManager) Push(control_type int, msg_pack *MessageObject) { 61 | // 添加到发消息通道 62 | if control_type == SEND_MSG { 63 | this.sendChannel.EnQueue(msg_pack) 64 | } else { 65 | // 添加到接受消息 66 | this.revChannel.EnQueue(msg_pack) 67 | } 68 | } 69 | 70 | // 弹出所有消息 71 | func (this *MessageManager) PopAll(control_type int) (msg_que []*MessageObject) { 72 | var temp []interface{} 73 | var count int 74 | if control_type == SEND_MSG { 75 | count = this.sendChannel.Count 76 | temp = this.sendChannel.DeQueueAll() 77 | } else { 78 | count = this.revChannel.Count 79 | temp = this.revChannel.DeQueueAll() 80 | } 81 | for i := 0; i < count; i++ { 82 | msg_que = append(msg_que, temp[i].(*MessageObject)) 83 | } 84 | return 85 | } 86 | 87 | // 消息编码 88 | func (this *MessageManager) Encode(handle msg_proto.MsgCmd, msg_body proto.Message) (encode_msg ByteMessage) { 89 | // 消息组成[255 00 00 22 22..],其中255为消息总长度含自身,00 00位代表消息的handle,22 22为消息本体 90 | // 其中handle最大为9999 91 | // 编码消息handle 92 | if _, ok := msg_conf.MessageMap[handle]; !ok { 93 | println("不存在消息handle!....SendMessage...1") 94 | return 95 | } 96 | msgId := int(handle) 97 | var byte_handle []byte 98 | if msgId < 100 { 99 | byte_handle = []byte{0, byte(msgId)} 100 | } else { 101 | hight := byte(math.Floor((float64(msgId)) / 100)) 102 | low := byte(msgId - int(hight)*100) 103 | byte_handle = []byte{hight, low} 104 | } 105 | 106 | // 消息体编码 107 | byte_msg_body, err := proto.Marshal(msg_body) 108 | if err != nil { 109 | println(err, " SendMessage....2") 110 | return 111 | } 112 | 113 | msg_len := len(byte_handle) + len(byte_msg_body) + 1 114 | encode_msg = append(encode_msg, byte(msg_len)) 115 | encode_msg = append(encode_msg, byte_handle...) 116 | encode_msg = append(encode_msg, byte_msg_body...) 117 | return 118 | } 119 | 120 | // 消息解码 121 | func (this *MessageManager) Decode(byte_msg ByteMessage) (msg_body proto.Message, msg_id msg_proto.MsgCmd, bOk bool) { 122 | // 消息组成[255 00 00 22 22..],其中255为消息总长度含自身,00 00位代表消息的handle,22 22为消息本体 123 | // 其中handle最大为9999 124 | if len(byte_msg) < 5 { 125 | println("消息长度过短,长度小于等于6,消息解码失败!........MessageManager.decode........1") 126 | bOk = false 127 | return 128 | } 129 | 130 | msg_id, bOk = this.GetMessageHandle(byte_msg) 131 | if !bOk { 132 | println("解析消息名失败, 不存在此消息!") 133 | return 134 | } 135 | 136 | msg_prototype := msg_conf.MessageMap[msg_id].MsgObj 137 | 138 | defer func() { 139 | if r := recover(); r != nil { 140 | println("消息解码失败!返回正常流程!", r, "......MessageManager.decode........3") 141 | } 142 | }() 143 | 144 | // 生成新消息实例 145 | msg_body = proto.Clone(msg_prototype) 146 | byte_msg_body := byte_msg[3:] 147 | if len(byte_msg_body) == 0 { 148 | bOk = false 149 | } else { 150 | proto.Unmarshal(byte_msg_body, msg_body) 151 | bOk = true 152 | } 153 | return msg_body, msg_id, bOk 154 | } 155 | 156 | // 获取消息名字 157 | func (this *MessageManager) GetMessageHandle(m ByteMessage) (msg_head msg_proto.MsgCmd, ok bool) { 158 | ok = false 159 | if len(m) < 1 { 160 | return 161 | } 162 | // 消息头 163 | byte_msg := m[1:3] 164 | msg_head = msg_proto.MsgCmd(byte_msg[0]*100 + byte_msg[1]) 165 | _, ok = msg_conf.MessageMap[msg_head] 166 | return 167 | } 168 | 169 | // 发送消息 170 | func (this *MessageManager) SendMessage(msg_id msg_proto.MsgCmd, sid string, msg_body proto.Message, isbc bool) { 171 | byte_msg := this.Encode(msg_id, msg_body) 172 | msg_obj := &MessageObject{ 173 | Sid: sid, 174 | ID: msg_id, 175 | Byte_Msg_body: byte_msg, 176 | IsBc: isbc, 177 | } 178 | this.Push(SEND_MSG, msg_obj) 179 | } 180 | 181 | // 接收消息 182 | func (this *MessageManager) ReceiveMessage(sid string, byte_msg ByteMessage) { 183 | msg, msg_id, bOk := this.Decode(byte_msg) 184 | if !bOk { 185 | println("接收消息失败!") 186 | return 187 | } 188 | msg_obj := &MessageObject{ 189 | Sid: sid, 190 | ID: msg_id, 191 | Proto_Msg_body: msg, 192 | } 193 | this.Push(REV_MSG, msg_obj) 194 | } 195 | 196 | // 创建byte消息Obj 197 | func (this *MessageManager) CreateByteMessage(sid string, byte_msg ByteMessage) (msg_obj *MessageObject) { 198 | msg_obj = new(MessageObject) 199 | msg_obj.Sid = sid 200 | msg_obj.Byte_Msg_body = byte_msg 201 | return 202 | } 203 | -------------------------------------------------------------------------------- /src/framework/network/proxymanager.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "common" 5 | ) 6 | 7 | const ( 8 | MAX_PROXY = 9999 9 | ) 10 | 11 | // 代理,用于后端服务器 12 | type Proxy struct { 13 | Sid string // 会话Id 14 | FrontendType string //连接的前端服务类型 15 | FrontendID int // 连接的前端服务器ID 16 | } 17 | 18 | func (this *Proxy) Reset() { 19 | this.Sid = "" 20 | this.FrontendType = "" 21 | this.FrontendID = 0 22 | } 23 | 24 | // 代理管理器 25 | type ProxyManager struct { 26 | *common.Pool 27 | proxyMap *common.BeeMap // 代理Map,proxyMap[sid]=Proxy 28 | } 29 | 30 | func NewProxyManager() *ProxyManager { 31 | return &ProxyManager{ 32 | Pool: common.NewPool(MAX_PROXY), 33 | proxyMap: common.NewBeeMap(), 34 | } 35 | } 36 | 37 | // 创建代理 38 | func (this *ProxyManager) CreateProxy(sid, frontendType string, frontendID int) *Proxy { 39 | obj, bOk := this.Borrow() 40 | var p *Proxy 41 | if !bOk { 42 | p = new(Proxy) 43 | } else { 44 | obj.Reset() 45 | p = obj.(*Proxy) 46 | } 47 | p.Sid = sid 48 | p.FrontendType = frontendType 49 | p.FrontendID = frontendID 50 | this.proxyMap.Set(sid, p) 51 | return p 52 | } 53 | 54 | // 销毁代理 55 | func (this *ProxyManager) DestroyProxy(sid string) { 56 | if !this.proxyMap.Check(sid) { 57 | return 58 | } 59 | p := this.proxyMap.Get(sid).(*Proxy) 60 | this.proxyMap.Delete(sid) 61 | this.GiveBack(p) 62 | } 63 | 64 | // 查找代理 65 | func (this *ProxyManager) FindProxy(sid string) *Proxy { 66 | if !this.proxyMap.Check(sid) { 67 | return nil 68 | } 69 | return this.proxyMap.Get(sid).(*Proxy) 70 | } 71 | -------------------------------------------------------------------------------- /src/framework/network/session.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | // 会话组件 4 | import ( 5 | "common" 6 | "crypto/rand" 7 | "encoding/base64" 8 | "io" 9 | "net" 10 | "time" 11 | ) 12 | 13 | // 暂定10000个会话 14 | const MAX_SESSION = 10000 15 | 16 | // 会话 17 | type Session struct { 18 | net.Conn // 通用性连接 19 | SId string // 会话id 20 | bVerify bool // 是否已经验证 21 | ConnTime *time.Time // 上次链接时间 22 | } 23 | 24 | func (this *Session) Reset() { 25 | this.Conn = nil 26 | this.SId = "" 27 | this.ConnTime = nil 28 | } 29 | 30 | // 会话管理器 31 | type SessionManager struct { 32 | *common.Pool // 用于回收session对象 33 | SessionMap *common.BeeMap // 会话列表,map[sid]=session 34 | Count int // 当前会话数量 35 | } 36 | 37 | func NewSessionManager() *SessionManager { 38 | return &SessionManager{ 39 | SessionMap: common.NewBeeMap(), 40 | Pool: common.NewPool(MAX_SESSION), 41 | } 42 | } 43 | 44 | // 随机一个会话id 45 | func (this *SessionManager) randSessionId() string { 46 | b := make([]byte, 32) 47 | if _, err := io.ReadFull(rand.Reader, b); err != nil { 48 | return "" 49 | } 50 | return base64.URLEncoding.EncodeToString(b) 51 | } 52 | 53 | // 创建会话 54 | func (this *SessionManager) CreateSession(conn net.Conn, conn_time *time.Time) *Session { 55 | if this.Count >= MAX_SESSION { 56 | println("会话达到最大数量!") 57 | return nil 58 | } 59 | obj, bOk := this.Borrow() 60 | if !bOk { 61 | obj = new(Session) 62 | } 63 | se := obj.(*Session) 64 | se.Conn = conn 65 | se.ConnTime = conn_time 66 | se.SId = this.randSessionId() 67 | return se 68 | } 69 | 70 | // 添加会话 71 | func (this *SessionManager) AddSession(se *Session) { 72 | if !this.SessionMap.Check(se.SId) { 73 | println("已存在此会话,id = ", se.SId) 74 | return 75 | } 76 | this.Count++ 77 | this.SessionMap.Set(se.SId, se) 78 | } 79 | 80 | // 删除会话 81 | func (this *SessionManager) RemoveSession(SId string) { 82 | var se *Session 83 | if !this.SessionMap.Check(SId) { 84 | println("不存在此会话,id = ", SId) 85 | return 86 | } 87 | se = this.SessionMap.Get(SId).(*Session) 88 | this.SessionMap.Delete(SId) 89 | // 归还给pool 90 | this.DestorySession(se) 91 | this.Count-- 92 | } 93 | 94 | // 销毁会话 95 | func (this *SessionManager) DestorySession(se *Session) { 96 | this.GiveBack(se) 97 | } 98 | 99 | // 通过Conn查找session 100 | func (this *SessionManager) FindSessionByConn(conn net.Conn) (se *Session) { 101 | this.SessionMap.Foreach(func(k, v interface{}) bool { 102 | session := v.(*Session) 103 | if session.Conn == conn { 104 | se = session 105 | return true 106 | } 107 | return false 108 | }) 109 | return 110 | } 111 | 112 | // 通过Sid查找session 113 | func (this *SessionManager) FindSessionBySID(sid string) (se *Session) { 114 | if !this.SessionMap.Check(sid) { 115 | return 116 | } 117 | se = this.SessionMap.Get(sid).(*Session) 118 | return 119 | } 120 | -------------------------------------------------------------------------------- /src/framework/server/backend.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "common" 5 | . "framework/network" 6 | ) 7 | 8 | const ( 9 | RECEIVER_MESSAGE = "ReceiveMessage" 10 | ) 11 | 12 | // 后端服务器 13 | type BackendServer struct { 14 | *BaseServer 15 | //*ProxyManager // 代理模块 16 | } 17 | 18 | func NewBackendServer(server_type string) *BackendServer { 19 | instance := new(BackendServer) 20 | instance.BaseServer = NewBaseServer(server_type) 21 | return instance 22 | } 23 | 24 | // 初始化 25 | func (this *BackendServer) Init() { 26 | this.BaseServer.Init() 27 | this.StartRPCService(this.Addr, this.Port) 28 | } 29 | 30 | // 逻辑循环 31 | func (this *BackendServer) LogicLoop() { 32 | } 33 | 34 | // 发送请求 35 | func (this *BackendServer) SendRequest(t *common.Timer, args ...interface{}) bool { 36 | // 把接收的消息抽取出来 37 | msg_que := this.MessageManager.PopAll(SEND_MSG) 38 | rpc_client_list := this.GetRPCClients() 39 | // 分派消息 40 | for i, v := range msg_que { 41 | proxy := this.FindProxy(v.Sid) 42 | if proxy == nil { 43 | continue 44 | } 45 | for j, client := range rpc_client_list { 46 | if client.GetRemoteServerType() == proxy.FrontendType { 47 | if v.IsBc { 48 | rpc_client_list[j].PushRequest(msg_que[i]) 49 | } else { 50 | if proxy.FrontendID == client.GetRemoteServerID() { 51 | rpc_client_list[j].PushRequest(msg_que[i]) 52 | break 53 | } 54 | } 55 | } 56 | } 57 | } 58 | // 发送消息 59 | for i := range rpc_client_list { 60 | rpc_client_list[i].RemoteCall(RECEIVER_MESSAGE) 61 | } 62 | return true 63 | } 64 | -------------------------------------------------------------------------------- /src/framework/server/frontend.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "common" 5 | "config/message_config" 6 | . "framework/network" 7 | //"msg_proto" 8 | "net" 9 | //"strings" 10 | "time" 11 | ) 12 | 13 | const ( 14 | ROUTE_REV_FUNC = "RouteMessage" 15 | ROUTE_REQUEST_INTERVAL = 20 // 路由请求的时间间隔,单位:毫秒 16 | ) 17 | 18 | // 路由规则 19 | type RouterPolicy func([]*ConnClient, *MessageObject) 20 | 21 | // 前端服务器 22 | type FrontendServer struct { 23 | *BaseServer 24 | routerPolicy map[string]RouterPolicy // 路由规则列表,格式:map[server_type]RouterPolicy 25 | routeTimer *common.Timer // 路由请求定时器 26 | } 27 | 28 | func NewFrontendServer(server_type string) *FrontendServer { 29 | instance := &FrontendServer{ 30 | routerPolicy: make(map[string]RouterPolicy), 31 | } 32 | instance.BaseServer = NewBaseServer(server_type) 33 | return instance 34 | } 35 | 36 | // 初始化 37 | func (this *FrontendServer) Init() { 38 | this.BaseServer.Init() 39 | // 添加tcp请求监听 40 | this.AddTCPRequestCallback(this.tcpRequestCallback) 41 | // 启动tpc服务 42 | this.StartTCPService(this.Addr, this.ClientPort) 43 | this.StartRPCService(this.Addr, this.Port) 44 | // 路由请求定时器 45 | this.routeTimer = common.NewTimer(time.Millisecond*ROUTE_REQUEST_INTERVAL, 0, true, this.RouteFlush) 46 | } 47 | 48 | func (this *FrontendServer) Run() { 49 | // 启动路由请求定时器 50 | this.routeTimer.Start() 51 | // 必须最后才能调用,以进入逻辑循环 52 | this.BaseServer.Run() 53 | } 54 | 55 | // tcp请求回调,用于处理通道接收到的消息 56 | func (this *FrontendServer) tcpRequestCallback(conn net.Conn, rev [][]byte) { 57 | se := this.FindSessionByConn(conn) 58 | if se == nil { 59 | println("会话不存在!") 60 | return 61 | } 62 | for _, request := range rev { 63 | msg_obj := this.CreateByteMessage(se.SId, request) 64 | this.RouteRequest(msg_obj) 65 | } 66 | } 67 | 68 | // 添加路由规则 69 | func (this *FrontendServer) AddRouterPolicy(server_type string, policy RouterPolicy) { 70 | if _, bOk := this.routerPolicy[server_type]; bOk { 71 | return 72 | } 73 | this.routerPolicy[server_type] = policy 74 | } 75 | 76 | // 执行路由 77 | func (this *FrontendServer) DoRoute(server_type string, client_list []*ConnClient, msg_obj *MessageObject) { 78 | var policy RouterPolicy 79 | var bOk bool 80 | if policy, bOk = this.routerPolicy[server_type]; !bOk { 81 | this.doDefaultRoute(client_list, msg_obj) 82 | } else { 83 | policy(client_list, msg_obj) 84 | } 85 | } 86 | 87 | // 执行默认路由 88 | func (this *FrontendServer) doDefaultRoute(client_list []*ConnClient, msg_obj *MessageObject) { 89 | // 把信息全部存到符合条件的所有客户端 90 | for i := range client_list { 91 | client_list[i].PushRequest(msg_obj) 92 | } 93 | } 94 | 95 | // 路由请求,仅仅把请求分类 96 | func (this *FrontendServer) RouteRequest(msg_obj *MessageObject) { 97 | // 获取消息Handle 98 | msg_id, bOk := this.GetMessageHandle(msg_obj.Byte_Msg_body) 99 | //server_type := strings.Split(handle, "_")[0] 100 | var server_type string 101 | if !bOk { 102 | return 103 | } 104 | server_type, bOk = msg_conf.GetMsgServerType(msg_id) 105 | if !bOk { 106 | return 107 | } 108 | // 查找远程客户端列表 109 | rpc_client_list := this.FindRPCClient(server_type) 110 | if len(rpc_client_list) <= 0 { 111 | return 112 | } 113 | // 本地消息则放入接消息通道 114 | if server_type == this.Type { 115 | this.ReceiveMessage(msg_obj.Sid, msg_obj.Byte_Msg_body) 116 | } else { 117 | // 路由消息 118 | this.DoRoute(server_type, rpc_client_list, msg_obj) 119 | } 120 | } 121 | 122 | // 转发所有请求,真正转发所有消息,需要定时转发 123 | func (this *FrontendServer) RouteFlush(t *common.Timer, args ...interface{}) bool { 124 | rpc_clients := this.GetRPCClients() 125 | for i := range rpc_clients { 126 | rpc_clients[i].RemoteCall(ROUTE_REV_FUNC) 127 | } 128 | return true 129 | } 130 | 131 | // 逻辑循环 132 | func (this *FrontendServer) LogicLoop() { 133 | } 134 | 135 | // 发送消息到客户端 136 | func (this *FrontendServer) SendRequest(t *common.Timer, args ...interface{}) bool { 137 | channel_lock := this.GetChannelLock() 138 | channel_lock.Lock() 139 | defer channel_lock.Unlock() 140 | channel_list := this.GetAllConnChannel() 141 | msg_list := this.MessageManager.PopAll(SEND_MSG) 142 | for _, v := range msg_list { 143 | for j, channel := range channel_list { 144 | if v.IsBc { 145 | channel_list[j].WriteBytes(v.Byte_Msg_body) 146 | } else { 147 | client_conn := this.FindSessionBySID(v.Sid) 148 | if client_conn == channel_list[j].GetConn() { 149 | channel.WriteBytes(v.Byte_Msg_body) 150 | } 151 | } 152 | } 153 | } 154 | 155 | for i := range channel_list { 156 | channel_list[i].ConnWrite() 157 | } 158 | return true 159 | } 160 | 161 | // 关闭会话 162 | func (this *FrontendServer) CloseSession(se *Session) { 163 | this.CloseConnChannel(se.Conn) 164 | this.RemoveSession(se.SId) 165 | } 166 | -------------------------------------------------------------------------------- /src/framework/server/iserver.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "common" 5 | "net" 6 | ) 7 | 8 | // 服务器接口 9 | type IServer interface { 10 | Init() // 初始化 11 | Run() // 启动 12 | LogicLoop() // 具体服务器的逻辑循环 13 | SendRequest(t *common.Timer, args ...interface{}) bool // 发送请求 14 | HandleRequest() // 处理请求 15 | GetBaseServer() *BaseServer // 获取基本服务器 16 | TcpListenerCallback(conn net.Conn) // tcp监听回调 17 | } 18 | -------------------------------------------------------------------------------- /src/framework/server/rpcservice.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | . "framework/network" 5 | ) 6 | 7 | type BindProxyArg struct { 8 | Sid string 9 | ServerType string 10 | ServerID int 11 | } 12 | 13 | // rpc服务 14 | type RPCService struct { 15 | ServerInterface IServer // 传入的服务器接口 16 | } 17 | 18 | // 接收到路由的消息(后端使用) 19 | func (this *RPCService) RouteMessage(msg_list []*MessageObject, pbOk *bool) error { 20 | this.ServerInterface.GetBaseServer().PushRevMessage(msg_list) 21 | *pbOk = true 22 | return nil 23 | } 24 | 25 | // 接收后端消息(前端) 26 | func (this *RPCService) ReceiveMessage(msg_list []*MessageObject, pbOk *bool) error { 27 | this.ServerInterface.GetBaseServer().PushSendMessage(msg_list) 28 | *pbOk = true 29 | return nil 30 | } 31 | 32 | // 绑定代理 33 | func (this *RPCService) BindProxy(arg *BindProxyArg, bOk *bool) error { 34 | this.ServerInterface.GetBaseServer().BindProxy(arg.Sid, arg.ServerType, arg.ServerID) 35 | *bOk = true 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /src/framework/server/server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | // 基础服务器 4 | import ( 5 | "common" 6 | "config/message_config" 7 | "config/server_config" 8 | . "framework/network" 9 | "log" 10 | "net" 11 | "net/rpc" 12 | "os" 13 | "runtime" 14 | "strconv" 15 | "strings" 16 | "time" 17 | ) 18 | 19 | const ( 20 | LOGIC_INTERVAL = 10 // 逻辑循环时间间隔,单位:毫秒 21 | SEND_REQUEST_INTERVAL = 20 // 发送请求的时间间隔,单位:毫秒 22 | SERVER_CONFIG = "LiveServer\\bin\\config\\server.json" // 配置文件路径 23 | SERVER_DIR = "liveserver" // 服务器所在目录 24 | ) 25 | 26 | type BaseServer struct { 27 | // 相关模块 28 | *Connection // 连接 29 | *SessionManager //会话管理 30 | *MessageManager // 消息管理器 31 | *ProxyManager // 代理管理器 32 | rpcService interface{} // rpc服务 33 | logicTimer *common.Timer // 逻辑循环的定时器 34 | sendTimer *common.Timer // 发送请求定时器 35 | IServer // 服务器接口 36 | 37 | // Server自身的属性 38 | Type string //服务器类型 39 | ID int // 服务器ID 40 | Addr string // 分开的地址 41 | Port string // 服务器端口 42 | ClientPort string // 用于客户端连接的端口 43 | TCPAddr string // tcp地址,addr:port 44 | RPCAddr string // rpc地址,addr:port 45 | } 46 | 47 | func NewBaseServer(server_type string) *BaseServer { 48 | return &BaseServer{ 49 | Connection: NewConnection(), 50 | SessionManager: NewSessionManager(), 51 | MessageManager: NewMessageManager(), 52 | ProxyManager: NewProxyManager(), 53 | Type: server_type, 54 | } 55 | } 56 | 57 | // 初始化服务器 58 | func (this *BaseServer) Init() { 59 | // 读取配置 60 | this.LoadServerConfig() 61 | // 设置ID 62 | this.SetServerID() 63 | // 设置地址 64 | this.SetupAddr() 65 | // 进行连接远程服务器 66 | go this.StartConnectRemoteServer() 67 | } 68 | 69 | // 启动服务器 70 | func (this *BaseServer) Run() { 71 | // 服务器以定时器为主循环 72 | this.logicTimer = common.NewTimer(time.Millisecond*LOGIC_INTERVAL, 0, false, this.MainLoop) 73 | // 发送请求定时器 74 | this.sendTimer = common.NewTimer(time.Millisecond*SEND_REQUEST_INTERVAL, 0, true, this.IServer.SendRequest) 75 | // 启动定时器 76 | this.logicTimer.Start() 77 | this.sendTimer.Start() 78 | //// 退出服务器循环直接退出进程 79 | //os.Exit(1) 80 | } 81 | 82 | // 服务器主循环,消息处理,逻辑暂时放在一起 83 | func (this *BaseServer) MainLoop(timer *common.Timer, args ...interface{}) bool { 84 | // 处理请求 85 | this.IServer.HandleRequest() 86 | // 逻辑循环 87 | this.IServer.LogicLoop() 88 | runtime.Gosched() 89 | return true 90 | } 91 | 92 | // 启动TCP服务 93 | func (this *BaseServer) StartTCPService(address, port string) { 94 | listener := this.CreateTCPListener(address, port) 95 | this.TCPAddr = address + ":" + port 96 | if listener == nil { 97 | return 98 | } 99 | bOk := this.AddListener("tcp", listener) 100 | if !bOk { 101 | return 102 | } 103 | // 添加监听 104 | this.AddTCPListenerCallback(this.IServer.TcpListenerCallback) 105 | // 监听为循环,需要开goroutine进行维护 106 | go this.RunTCPListen(listener) 107 | } 108 | 109 | // 注册rpc 110 | func (this *BaseServer) RegisterRPC(rpc_handle interface{}) { 111 | this.rpcService = rpc_handle 112 | rpc.Register(rpc_handle) 113 | } 114 | 115 | // 启动RPC服务 116 | func (this *BaseServer) StartRPCService(address, port string) { 117 | listener := this.CreateTCPListener(address, port) 118 | this.RPCAddr = address + ":" + port 119 | if listener == nil { 120 | return 121 | } 122 | bOk := this.AddListener("rpc", listener) 123 | if !bOk { 124 | return 125 | } 126 | // 监听为循环,需要开goroutine进行维护 127 | this.RunRPCListen(listener) 128 | } 129 | 130 | // tcp监听回调,此函数已用goroutine维护(此方法可以被重写) 131 | func (this *BaseServer) TcpListenerCallback(conn net.Conn) { 132 | conn_time := time.Now() 133 | se := this.CreateSession(conn, &conn_time) 134 | if se == nil { 135 | conn.Close() 136 | this.DestorySession(se) 137 | return 138 | } 139 | this.AddSession(se) 140 | // 创建连接通道 141 | channel := this.BuildConnChannel(conn) 142 | // 接收连接消息请求 143 | this.AcceptTCPConnRequest(channel) 144 | } 145 | 146 | // 获取基本服务器 147 | func (this *BaseServer) GetBaseServer() *BaseServer { 148 | return this 149 | } 150 | 151 | // 放置接受的消息 152 | func (this *BaseServer) PushRevMessage(msg_list []*MessageObject) { 153 | for _, v := range msg_list { 154 | this.ReceiveMessage(v.Sid, v.Byte_Msg_body) 155 | } 156 | } 157 | 158 | // 放置发送的消息(后端发送到前端的消息) 159 | func (this *BaseServer) PushSendMessage(msg_list []*MessageObject) { 160 | for _, v := range msg_list { 161 | this.MessageManager.Push(SEND_MSG, v) 162 | } 163 | } 164 | 165 | // 绑定代理 166 | func (this *BaseServer) BindProxy(sid, server string, server_id int) { 167 | this.CreateProxy(sid, server, server_id) 168 | } 169 | 170 | // 读取服务器配置文件 171 | func (this *BaseServer) LoadServerConfig() { 172 | // 全局配置只读一次 173 | if server_conf.IsReadConfig() { 174 | return 175 | } 176 | server_conf.ReadConfig(true) 177 | conf := server_conf.GetSingleton() 178 | conf_dir := common.GetDir() 179 | if conf_dir == "" { 180 | println("读取服务器配置文件失败!") 181 | os.Exit(1) 182 | } 183 | conf_slice := strings.Split(conf_dir, "\\") 184 | var index int = -1 185 | for i, v := range conf_slice { 186 | if strings.ToLower(v) == SERVER_DIR { 187 | index = i 188 | break 189 | } 190 | } 191 | if index == -1 { 192 | println("请把服务器拷贝到liveserver下,读取服务器配置文件失败!") 193 | os.Exit(1) 194 | } 195 | var conf_path string 196 | for i := 0; i < index; i++ { 197 | conf_path += conf_slice[i] + "\\" 198 | } 199 | conf_path += SERVER_CONFIG 200 | common.ReadJson(conf_path, conf) 201 | 202 | // 转换 203 | conf.ConvertToMap() 204 | } 205 | 206 | // 读取服务器启动参数 207 | func (this *BaseServer) SetServerID() { 208 | args := os.Args 209 | if len(args) < 3 { 210 | this.ID = 1 211 | //println("ID = ", this.ID) 212 | return 213 | } 214 | id, err := strconv.ParseInt(args[2], 10, 0) 215 | if err != nil || id == 0 { 216 | this.ID = 1 217 | } else { 218 | this.ID = int(id) 219 | } 220 | } 221 | 222 | // 设置服务器地址 223 | func (this *BaseServer) SetupAddr() { 224 | if !server_conf.IsReadConfig() { 225 | println("没有读取服务器配置!") 226 | os.Exit(1) 227 | return 228 | } 229 | //println("type = ", this.Type, " id = ", this.ID) 230 | if this.Type == "" || this.ID == 0 { 231 | println("没有设置服务器类型或者服务器ID") 232 | os.Exit(1) 233 | return 234 | } 235 | 236 | conf := server_conf.GetSingleton() 237 | conf_elem := conf.GetConfig(this.Type, this.ID) 238 | if conf_elem == nil { 239 | println("没有配置此服务器!") 240 | os.Exit(1) 241 | return 242 | } 243 | this.Addr = conf_elem.Host 244 | this.Port = conf_elem.Port 245 | this.RPCAddr = this.Addr + ":" + this.Port 246 | if conf_elem.Fronted { 247 | this.ClientPort = conf_elem.ClientPort 248 | this.TCPAddr = this.Addr + ":" + this.ClientPort 249 | } 250 | } 251 | 252 | // 进行RPC连接 253 | func (this *BaseServer) StartConnectRemoteServer() { 254 | if !server_conf.IsReadConfig() { 255 | log.Println("没有读取服务器配置!") 256 | return 257 | } 258 | conf := server_conf.GetSingleton() 259 | for k := range conf.ConfigMap { 260 | if k == this.Type { 261 | continue 262 | } 263 | for i := range conf.ConfigMap[k] { 264 | server_conf := conf.ConfigMap[k][i] 265 | log.Println("开始连接", k, " ", server_conf.Id) 266 | this.ConnectRPCServer(server_conf.Host, server_conf.Port, server_conf.Type, server_conf.Id) 267 | } 268 | } 269 | log.Println("连接远程服务器成功!") 270 | } 271 | 272 | // 处理客户端请求 273 | func (this *BaseServer) HandleRequest() { 274 | msg_list := this.MessageManager.PopAll(REV_MSG) 275 | msg_callback := msg_conf.MessageCallback() 276 | for _, v := range msg_list { 277 | msg_callback.Handle(v.ID, v.Sid, v.Proto_Msg_body) 278 | } 279 | } 280 | 281 | // 异步rpc调用 282 | func (this *BaseServer) RPCCall(server_type string, server_id int, fun string, arg_1 interface{}, arg_2 interface{}) { 283 | list := this.FindPRCClientsByDetail(server_type, server_id) 284 | for _, v := range list { 285 | go v.Call(fun, arg_1, arg_2) 286 | } 287 | } 288 | 289 | // 同步rpc调用 290 | func (this *BaseServer) RPCSyncCall(server_type string, server_id int, fun string, arg_1 interface{}, arg_2 interface{}) { 291 | list := this.FindPRCClientsByDetail(server_type, server_id) 292 | for _, v := range list { 293 | v.Call(fun, arg_1, arg_2) 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /src/gamelogic/rpc/rpcarg.go: -------------------------------------------------------------------------------- 1 | package game_rpc 2 | 3 | import ( 4 | "gopkg.in/mgo.v2/bson" 5 | "msg_proto" 6 | ) 7 | 8 | // 连接数量 9 | type ConnState struct { 10 | Name string // 服务器名 11 | Type string // 服务器类型 12 | Id int // 服务器Id 13 | Num int // 连接数 14 | } 15 | 16 | // 用户信息 17 | type UserLoginInfo struct { 18 | Sid string 19 | LoginInfo msg_proto.RequestLogin // 登录信息 20 | UserId bson.ObjectId // 数据库ID 21 | Error msg_proto.Error // 错误码 22 | } 23 | -------------------------------------------------------------------------------- /src/gameserver/auth/app/auth_app.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | // 第三方平台验证服 4 | import ( 5 | "common" 6 | . "framework/database" 7 | . "framework/server" 8 | "gopkg.in/mgo.v2/bson" 9 | "time" 10 | ) 11 | 12 | const ( 13 | AUTH_DB = "auth" // 验证数据库名 14 | AUTH_DB_TABLE = "user" // 数据表名 15 | UPDATE_DURTIME = 15 // 分钟更新一下数据 16 | ) 17 | 18 | type AuthData struct { 19 | Id_ bson.ObjectId `bson:"_id"` // 数据ID 20 | User string // 用户名 21 | Password string // 密码 22 | UserID bson.ObjectId // 关联的用户数据ID 23 | } 24 | 25 | type Auth struct { 26 | *BackendServer 27 | db *DB // 数据库 28 | dataTimer *common.Timer 29 | userMap *common.BeeMap // 用户列表,map[username]=AuthData 30 | } 31 | 32 | func NewAuth(server_type string) *Auth { 33 | instance := &Auth{ 34 | BackendServer: NewBackendServer(server_type), 35 | db: NewDB(AUTH_DB), 36 | userMap: common.NewBeeMap(), 37 | } 38 | instance.IServer = instance 39 | // 注册RPC 40 | instance.RegisterRPC(&AuthRPCService{&RPCService{ServerInterface: instance}}) 41 | // 初始化 42 | instance.Init() 43 | return instance 44 | } 45 | 46 | func (this *Auth) Init() { 47 | this.BackendServer.Init() 48 | // 添加初始化完成后事件 49 | this.db.InitCallback = this.DBFinInitCallback 50 | // 初始化数据库 51 | go this.db.Init() 52 | } 53 | 54 | // 数据库模块启动完成回调 55 | func (this *Auth) DBFinInitCallback() { 56 | this.dataTimer = common.NewTimer(time.Minute*UPDATE_DURTIME, 0, true, this.UpdateData) 57 | this.dataTimer.Start() 58 | // 第一次就开始更新 59 | this.UpdateData(this.dataTimer) 60 | } 61 | 62 | // 定时更新数据 63 | func (this *Auth) UpdateData(t *common.Timer, arg ...interface{}) bool { 64 | var data_list []AuthData 65 | this.db.FindAll(AUTH_DB_TABLE, &data_list) 66 | for _, v := range data_list { 67 | this.userMap.Set(v.User, &v) 68 | } 69 | return true 70 | } 71 | -------------------------------------------------------------------------------- /src/gameserver/auth/app/auth_rpc.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | . "framework/server" 5 | "gamelogic/rpc" 6 | "msg_proto" 7 | ) 8 | 9 | type AuthRPCService struct { 10 | *RPCService 11 | } 12 | 13 | // 验证用户密码 14 | func (this *AuthRPCService) AuthTest(arg *game_rpc.UserLoginInfo, result *game_rpc.UserLoginInfo) error { 15 | server := this.ServerInterface.(*Auth) 16 | result = &(*arg) 17 | user := arg.LoginInfo.GetUsername() 18 | if server.userMap.Check(user) { 19 | pw := server.userMap.Get(user).(*AuthData) 20 | // 验证密码成功 21 | if pw.Password == arg.LoginInfo.GetPassword() { 22 | result.Error = msg_proto.Error_Sucess 23 | result.UserId = server.userMap.Get(user).(*AuthData).UserID 24 | } else { 25 | // 密码不匹配 26 | result.Error = msg_proto.Error_Mismatch_Password 27 | } 28 | } else { 29 | // 不存在用户 30 | result.Error = msg_proto.Error_UnKnow_User 31 | } 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /src/gameserver/bin.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/src/gameserver/bin.lnk -------------------------------------------------------------------------------- /src/gameserver/connector/app/connector_app.go: -------------------------------------------------------------------------------- 1 | package connector 2 | 3 | // 连接服 4 | import ( 5 | "framework/network" 6 | . "framework/server" 7 | "gamelogic/rpc" 8 | "net" 9 | "strconv" 10 | ) 11 | 12 | type Connector struct { 13 | *FrontendServer 14 | *SessionCheck // 检查会话 15 | *TokenManager 16 | } 17 | 18 | func NewConnector(server_type string) *Connector { 19 | instance := &Connector{ 20 | FrontendServer: NewFrontendServer(server_type), 21 | SessionCheck: NewSessionCheck(), 22 | TokenManager: NewTokenManager(), 23 | } 24 | instance.IServer = instance 25 | // 注册RPC 26 | instance.RegisterRPC(&ConnectorRPCService{&RPCService{ServerInterface: instance}}) 27 | // 初始化 28 | instance.Init() 29 | return instance 30 | } 31 | 32 | // 重写初始化函数 33 | func (this *Connector) Init() { 34 | this.FrontendServer.Init() 35 | this.SessionCheck.SeTimeout = this.DeleteTimeoutSession 36 | } 37 | 38 | // 重写启动函数 39 | func (this *Connector) Run() { 40 | this.SessionCheck.Begin() 41 | this.TokenManager.Begin() 42 | this.FrontendServer.Run() 43 | } 44 | 45 | // 重写TCP监听 46 | func (this *Connector) TcpListenerCallback(conn net.Conn) { 47 | this.FrontendServer.TcpListenerCallback(conn) 48 | // 更新一下gete服的会话数 49 | this.UpdateConnNum() 50 | se := this.FindSessionByConn(conn) 51 | if se != nil { 52 | this.SessionCheck.Add(se) 53 | } 54 | } 55 | 56 | // 删除超时会话 57 | func (this *Connector) DeleteTimeoutSession(se *network.Session) { 58 | this.CloseSession(se) 59 | // 更新一下gete服的会话数 60 | this.UpdateConnNum() 61 | } 62 | 63 | // 更新连接数 64 | func (this *Connector) UpdateConnNum() { 65 | var bOk bool 66 | state := &game_rpc.ConnState{this.Type + strconv.Itoa(this.ID), this.Type, this.ID, this.SessionManager.Count} 67 | this.RPCCall("gate", 1, "SetConnectorConnNum", state, &bOk) 68 | } 69 | -------------------------------------------------------------------------------- /src/gameserver/connector/app/connector_rpc.go: -------------------------------------------------------------------------------- 1 | package connector 2 | 3 | import ( 4 | . "framework/server" 5 | "msg_proto" 6 | ) 7 | 8 | type ConnectorRPCService struct { 9 | *RPCService 10 | } 11 | 12 | // 添加客户端的Token 13 | func (this *ConnectorRPCService) AddClientToken(arg *msg_proto.Token, bOk *bool) error { 14 | server := this.ServerInterface.(*Connector) 15 | token := *arg 16 | server.TokenManager.Add(&token) 17 | *bOk = true 18 | return nil 19 | } 20 | -------------------------------------------------------------------------------- /src/gameserver/connector/app/session_check.go: -------------------------------------------------------------------------------- 1 | package connector 2 | 3 | import ( 4 | "common" 5 | "container/list" 6 | "framework/network" 7 | "math" 8 | "sync" 9 | "time" 10 | ) 11 | 12 | const ( 13 | CHECK_DUTIME = 1 // 定时检查时间,为1分钟 14 | ) 15 | 16 | type TimeoutCallback func(se *network.Session) 17 | 18 | type SessionCheck struct { 19 | seList *list.List // 待验证的会话列表 20 | seCheckLock *sync.RWMutex // 验证会话锁 21 | checkTimer *common.Timer // 定时检查 22 | SeTimeout TimeoutCallback // 超时回调 23 | } 24 | 25 | func NewSessionCheck() *SessionCheck { 26 | sc := &SessionCheck{ 27 | seList: list.New(), 28 | seCheckLock: new(sync.RWMutex), 29 | } 30 | sc.checkTimer = common.NewTimer(time.Minute*CHECK_DUTIME, 0, true, sc.Check) 31 | return sc 32 | } 33 | 34 | // 开始检测 35 | func (this *SessionCheck) Begin() { 36 | this.checkTimer.Start() 37 | } 38 | 39 | // 检查会话 40 | func (this *SessionCheck) Check(t *common.Timer, arg ...interface{}) bool { 41 | this.seCheckLock.Lock() 42 | defer this.seCheckLock.Unlock() 43 | e := this.seList.Front() 44 | cur_t := float64(time.Now().UnixNano()) 45 | for { 46 | if e == nil { 47 | break 48 | } 49 | se := e.Value.(*network.Session) 50 | next := e.Next() 51 | dt := (float64(se.ConnTime.UnixNano()) - cur_t) / math.Pow(float64(10), float64(9)) 52 | if dt/float64(60) >= float64(CHECK_DUTIME) { 53 | this.seList.Remove(e) 54 | if this.SeTimeout != nil { 55 | this.SeTimeout(se) 56 | } 57 | } 58 | e = next 59 | } 60 | return true 61 | } 62 | 63 | // 添加待测会话 64 | func (this *SessionCheck) Add(se *network.Session) { 65 | this.seCheckLock.Lock() 66 | defer this.seCheckLock.Unlock() 67 | this.seList.PushBack(se) 68 | } 69 | 70 | // 移除会话 71 | func (this *SessionCheck) Remove(se *network.Session) { 72 | this.seCheckLock.Lock() 73 | defer this.seCheckLock.Unlock() 74 | var elem *list.Element 75 | l := this.seList 76 | for e := l.Front(); e != nil; e = e.Next() { 77 | if e.Value.(*network.Session) == se { 78 | elem = e 79 | break 80 | } 81 | } 82 | this.seList.Remove(elem) 83 | } 84 | -------------------------------------------------------------------------------- /src/gameserver/connector/app/token_manager.go: -------------------------------------------------------------------------------- 1 | package connector 2 | 3 | import ( 4 | "common" 5 | "container/list" 6 | . "msg_proto" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | const ( 12 | MAX_TOKEN_LIFE = 1 * 60 * 1000 // token的生命周期为1min 13 | ) 14 | 15 | type TokenManager struct { 16 | tokenList *list.List // tonken列表 17 | lock *sync.RWMutex 18 | lifeTimer *common.Timer // 生命周期定时器 19 | } 20 | 21 | func NewTokenManager() *TokenManager { 22 | tmgr := &TokenManager{ 23 | tokenList: list.New(), 24 | lock: new(sync.RWMutex), 25 | } 26 | tmgr.lifeTimer = common.NewTimer(time.Minute*MAX_TOKEN_LIFE, 0, true, tmgr.Check) 27 | return tmgr 28 | } 29 | 30 | // 启动Token管理器 31 | func (this *TokenManager) Begin() { 32 | this.lifeTimer.Start() 33 | } 34 | 35 | // 检查token是否过期 36 | func (this *TokenManager) Check(t *common.Timer, arg ...interface{}) bool { 37 | this.lock.Lock() 38 | defer this.lock.Unlock() 39 | cur_t := common.GetTime() 40 | e := this.tokenList.Front() 41 | for { 42 | if e == nil { 43 | break 44 | } 45 | next := e.Next() 46 | if e.Value.(*Token).GetConnTime()-cur_t >= int64(MAX_TOKEN_LIFE) { 47 | this.tokenList.Remove(e) 48 | } 49 | e = next 50 | } 51 | return true 52 | } 53 | 54 | // 添加token 55 | func (this *TokenManager) Add(token *Token) { 56 | this.lock.Lock() 57 | defer this.lock.Unlock() 58 | this.tokenList.PushBack(token) 59 | } 60 | 61 | // 删除token 62 | func (this *TokenManager) Remove(token *Token) { 63 | this.lock.Lock() 64 | defer this.lock.Unlock() 65 | var elem *list.Element 66 | for e := this.tokenList.Front(); e != nil; e.Next() { 67 | if e.Value.(*Token) == token { 68 | elem = e 69 | break 70 | } 71 | } 72 | this.tokenList.Remove(elem) 73 | } 74 | -------------------------------------------------------------------------------- /src/gameserver/database/app/database_app.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | // 数据库缓存服 4 | import ( 5 | . "framework/server" 6 | ) 7 | 8 | type DataBase struct { 9 | *BackendServer 10 | } 11 | 12 | func NewDataBase(server_type string) *DataBase { 13 | instance := &DataBase{ 14 | BackendServer: NewBackendServer(server_type), 15 | } 16 | instance.IServer = instance 17 | // 注册RPC 18 | instance.RegisterRPC(&DataBaseRPCService{&RPCService{ServerInterface: instance}}) 19 | // 初始化 20 | instance.Init() 21 | return instance 22 | } 23 | -------------------------------------------------------------------------------- /src/gameserver/database/app/database_rpc.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import ( 4 | . "framework/server" 5 | ) 6 | 7 | type DataBaseRPCService struct { 8 | *RPCService 9 | } 10 | -------------------------------------------------------------------------------- /src/gameserver/game/app/game_app.go: -------------------------------------------------------------------------------- 1 | package game 2 | 3 | // 游戏服 4 | import ( 5 | . "framework/server" 6 | ) 7 | 8 | type Game struct { 9 | *BackendServer 10 | } 11 | 12 | func NewGame(server_type string) *Game { 13 | instance := &Game{ 14 | BackendServer: NewBackendServer(server_type), 15 | } 16 | instance.IServer = instance 17 | // 注册RPC 18 | instance.RegisterRPC(&GameRPCService{&RPCService{ServerInterface: instance}}) 19 | // 初始化 20 | instance.Init() 21 | return instance 22 | } 23 | -------------------------------------------------------------------------------- /src/gameserver/game/app/game_rpc.go: -------------------------------------------------------------------------------- 1 | package game 2 | 3 | import ( 4 | . "framework/server" 5 | ) 6 | 7 | type GameRPCService struct { 8 | *RPCService 9 | } 10 | -------------------------------------------------------------------------------- /src/gameserver/gameserver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gtd138/LiveServer/e2ac0bb181d9c46463afda7a345b402e5eea68bc/src/gameserver/gameserver.exe -------------------------------------------------------------------------------- /src/gameserver/gameserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 服务器主程序 4 | import ( 5 | . "framework/server" 6 | . "gameserver/auth/app" 7 | . "gameserver/connector/app" 8 | . "gameserver/database/app" 9 | . "gameserver/game/app" 10 | . "gameserver/gate/app" 11 | . "gameserver/lobby/app" 12 | . "gameserver/master/app" 13 | . "gameserver/society/app" 14 | "log" 15 | "os" 16 | ) 17 | 18 | func main() { 19 | app := CreateServerApp() 20 | // app := DebugCreateServerApp() 21 | app.Run() 22 | } 23 | 24 | // 调试创建服务器 25 | func DebugCreateServerApp() (app IServer) { 26 | app = NewGate("gate") 27 | return 28 | } 29 | 30 | // 创建对应的服务器应用 31 | func CreateServerApp() (app IServer) { 32 | if len(os.Args) < 2 { 33 | log.Println("请输入服务器类型") 34 | os.Exit(1) 35 | } 36 | server_type := os.Args[1] 37 | switch server_type { 38 | case "connector": 39 | app = NewConnector(server_type) 40 | case "gate": 41 | app = NewGate(server_type) 42 | case "master": 43 | app = NewMaster(server_type) 44 | case "game": 45 | app = NewGame(server_type) 46 | case "database": 47 | app = NewDataBase(server_type) 48 | case "society": 49 | app = NewSociety(server_type) 50 | case "lobby": 51 | app = NewLobby(server_type) 52 | case "auth": 53 | app = NewAuth(server_type) 54 | } 55 | 56 | if app == nil { 57 | log.Println("启动的服务器类型不存在!") 58 | os.Exit(1) 59 | } 60 | return 61 | } 62 | -------------------------------------------------------------------------------- /src/gameserver/gate/app/gate_app.go: -------------------------------------------------------------------------------- 1 | package gate 2 | 3 | // 网关服 4 | import ( 5 | "common" 6 | "config/message_config" 7 | "config/server_config" 8 | . "framework/server" 9 | "gamelogic/rpc" 10 | "msg_proto" 11 | ) 12 | 13 | type Gate struct { 14 | *FrontendServer 15 | CotorStateMap *common.BeeMap // 连接服状态,map[name]=*ConnState 16 | } 17 | 18 | func NewGate(server_type string) *Gate { 19 | instance := &Gate{ 20 | FrontendServer: NewFrontendServer(server_type), 21 | CotorStateMap: common.NewBeeMap(), 22 | } 23 | instance.IServer = instance 24 | // 注册RPC 25 | instance.RegisterRPC(&GateRPCService{&RPCService{ServerInterface: instance}}) 26 | // 初始化 27 | instance.Init() 28 | return instance 29 | } 30 | 31 | func (this *Gate) Init() { 32 | this.RegisterMsgHandle() 33 | this.FrontendServer.Init() 34 | } 35 | 36 | // 注册消息回调 37 | func (this *Gate) RegisterMsgHandle() { 38 | reg_func := msg_conf.MessageCallback() 39 | reg_func.Register(msg_proto.MsgCmd_RequestLogin_C, this.RequestLogin) 40 | } 41 | 42 | // 获取最佳连接服 43 | func (this *Gate) GetFitConnector() (Type string, Id int, IP, Port string) { 44 | conn_num := -1 45 | var state *game_rpc.ConnState 46 | this.CotorStateMap.Foreach(func(k, v interface{}) bool { 47 | if conn_num == -1 { 48 | state = v.(*game_rpc.ConnState) 49 | conn_num = state.Num 50 | } 51 | if conn_num > v.(*game_rpc.ConnState).Num { 52 | conn_num = v.(*game_rpc.ConnState).Num 53 | state = v.(*game_rpc.ConnState) 54 | } 55 | return false 56 | }) 57 | if state == nil { 58 | println("获取适合的连接服失败!") 59 | return 60 | } 61 | Type = state.Type 62 | Id = state.Id 63 | config := server_conf.GetSingleton().GetConfig(state.Type, state.Id) 64 | IP = config.Host 65 | Port = config.Port 66 | return 67 | } 68 | -------------------------------------------------------------------------------- /src/gameserver/gate/app/gate_handle.go: -------------------------------------------------------------------------------- 1 | package gate 2 | 3 | // gate服的消息请求处理 4 | import ( 5 | // "code.google.com/p/goprotobuf/proto" 6 | "common" 7 | "gamelogic/rpc" 8 | "msg_proto" 9 | 10 | "github.com/golang/protobuf/proto" 11 | ) 12 | 13 | // 处理登录请求 14 | func (this *Gate) RequestLogin(sid string, message proto.Message) { 15 | rev := message.(*msg_proto.RequestLogin) 16 | arg := &game_rpc.UserLoginInfo{ 17 | Sid: sid, 18 | LoginInfo: *rev, 19 | Error: msg_proto.Error_Init_None, 20 | } 21 | // 获取账号验证结果 22 | go func(server *Gate) { 23 | result := &game_rpc.UserLoginInfo{} 24 | // 使用同步RPC 25 | this.RPCSyncCall("auth", 1, "AuthTest", arg, result) 26 | Type, Id, ip, port := server.GetFitConnector() 27 | switch result.Error { 28 | case msg_proto.Error_UnKnow_User: 29 | fallthrough 30 | case msg_proto.Error_Mismatch_Password: 31 | msg := &msg_proto.CmdResult{ 32 | ErrorCode: &(result.Error), 33 | } 34 | server.SendMessage(msg_proto.MsgCmd_CmdResult_S, result.Sid, msg, false) 35 | case msg_proto.Error_Sucess: 36 | token := &msg_proto.Token{ 37 | Sid: proto.String(result.Sid), 38 | Ip: proto.String(ip), 39 | Port: proto.String(port), 40 | ConnTime: proto.Int64(common.GetTime()), 41 | Pid: proto.String(result.UserId.Hex()), 42 | } 43 | var bOk *bool 44 | // 异步RPC 45 | server.RPCCall(Type, Id, "AddClientToken", token, bOk) 46 | // 发送消息给客户端 47 | server.SendMessage(msg_proto.MsgCmd_LoginToken_S, result.Sid, token, false) 48 | } 49 | }(this) 50 | } 51 | -------------------------------------------------------------------------------- /src/gameserver/gate/app/gate_rpc.go: -------------------------------------------------------------------------------- 1 | package gate 2 | 3 | import ( 4 | . "framework/server" 5 | "gamelogic/rpc" 6 | ) 7 | 8 | type GateRPCService struct { 9 | *RPCService 10 | } 11 | 12 | // 设置连接数量 13 | func (this *GateRPCService) SetConnectorConnNum(arg *game_rpc.ConnState, bOk *bool) error { 14 | *bOk = true 15 | server := this.ServerInterface.(*Gate) 16 | // 先拷贝一份 17 | state := *arg 18 | server.CotorStateMap.Set(state.Name, &state) 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /src/gameserver/lobby/app/lobby_app.go: -------------------------------------------------------------------------------- 1 | package lobby 2 | 3 | // 大厅服 4 | import ( 5 | . "framework/database" 6 | . "framework/server" 7 | ) 8 | 9 | type Lobby struct { 10 | *BackendServer 11 | db *DB // 数据库 12 | } 13 | 14 | func NewLobby(server_type string) *Lobby { 15 | instance := &Lobby{ 16 | BackendServer: NewBackendServer(server_type), 17 | db: NewDB("game"), 18 | } 19 | instance.IServer = instance 20 | // 注册RPC 21 | instance.RegisterRPC(&LobbyRPCService{&RPCService{ServerInterface: instance}}) 22 | // 初始化 23 | instance.Init() 24 | return instance 25 | } 26 | 27 | func (this *Lobby) Init() { 28 | this.BackendServer.Init() 29 | // 初始化数据库 30 | go this.db.Init() 31 | } 32 | -------------------------------------------------------------------------------- /src/gameserver/lobby/app/lobby_rpc.go: -------------------------------------------------------------------------------- 1 | package lobby 2 | 3 | import ( 4 | . "framework/server" 5 | ) 6 | 7 | type LobbyRPCService struct { 8 | *RPCService 9 | } 10 | -------------------------------------------------------------------------------- /src/gameserver/master/app/master_app.go: -------------------------------------------------------------------------------- 1 | package master 2 | 3 | // 监控服 4 | import ( 5 | . "framework/server" 6 | ) 7 | 8 | type Master struct { 9 | *BackendServer 10 | } 11 | 12 | func NewMaster(server_type string) *Master { 13 | instance := &Master{ 14 | BackendServer: NewBackendServer(server_type), 15 | } 16 | instance.IServer = instance 17 | // 注册RPC 18 | instance.RegisterRPC(&MasterRPCService{&RPCService{ServerInterface: instance}}) 19 | // 初始化 20 | instance.Init() 21 | return instance 22 | } 23 | -------------------------------------------------------------------------------- /src/gameserver/master/app/master_rpc.go: -------------------------------------------------------------------------------- 1 | package master 2 | 3 | import ( 4 | . "framework/server" 5 | ) 6 | 7 | type MasterRPCService struct { 8 | *RPCService 9 | } 10 | -------------------------------------------------------------------------------- /src/gameserver/society/app/society_app.go: -------------------------------------------------------------------------------- 1 | package society 2 | 3 | // 社会服 4 | import ( 5 | . "framework/server" 6 | ) 7 | 8 | type Society struct { 9 | *BackendServer 10 | } 11 | 12 | func NewSociety(server_type string) *Society { 13 | instance := &Society{ 14 | BackendServer: NewBackendServer(server_type), 15 | } 16 | instance.IServer = instance 17 | // 注册RPC 18 | instance.RegisterRPC(&SocietyRPCService{&RPCService{ServerInterface: instance}}) 19 | // 初始化 20 | instance.Init() 21 | return instance 22 | } 23 | -------------------------------------------------------------------------------- /src/gameserver/society/app/society_rpc.go: -------------------------------------------------------------------------------- 1 | package society 2 | 3 | import ( 4 | . "framework/server" 5 | ) 6 | 7 | type SocietyRPCService struct { 8 | *RPCService 9 | } 10 | -------------------------------------------------------------------------------- /src/msg_proto/error.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: error.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package msg_proto is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | error.proto 10 | frontend.proto 11 | gate.proto 12 | msgcmd.proto 13 | result.proto 14 | 15 | It has these top-level messages: 16 | Token 17 | RequestLogin 18 | CmdResult 19 | */ 20 | package msg_proto 21 | 22 | import proto "github.com/golang/protobuf/proto" 23 | import fmt "fmt" 24 | import math "math" 25 | 26 | // Reference imports to suppress errors if they are not otherwise used. 27 | var _ = proto.Marshal 28 | var _ = fmt.Errorf 29 | var _ = math.Inf 30 | 31 | type Error int32 32 | 33 | const ( 34 | Error_Init_None Error = -1 35 | Error_Sucess Error = 0 36 | Error_UnKnow_User Error = 1 37 | Error_Mismatch_Password Error = 2 38 | ) 39 | 40 | var Error_name = map[int32]string{ 41 | -1: "Init_None", 42 | 0: "Sucess", 43 | 1: "UnKnow_User", 44 | 2: "Mismatch_Password", 45 | } 46 | var Error_value = map[string]int32{ 47 | "Init_None": -1, 48 | "Sucess": 0, 49 | "UnKnow_User": 1, 50 | "Mismatch_Password": 2, 51 | } 52 | 53 | func (x Error) Enum() *Error { 54 | p := new(Error) 55 | *p = x 56 | return p 57 | } 58 | func (x Error) String() string { 59 | return proto.EnumName(Error_name, int32(x)) 60 | } 61 | func (x *Error) UnmarshalJSON(data []byte) error { 62 | value, err := proto.UnmarshalJSONEnum(Error_value, data, "Error") 63 | if err != nil { 64 | return err 65 | } 66 | *x = Error(value) 67 | return nil 68 | } 69 | func (Error) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 70 | 71 | func init() { 72 | proto.RegisterEnum("msg_proto.Error", Error_name, Error_value) 73 | } 74 | 75 | var fileDescriptor0 = []byte{ 76 | // 121 bytes of a gzipped FileDescriptorProto 77 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0x2d, 0x2a, 0xca, 78 | 0x2f, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xcc, 0x2d, 0x4e, 0x8f, 0x07, 0x33, 0xb5, 79 | 0x82, 0xb9, 0x58, 0x5d, 0x41, 0x32, 0x42, 0x62, 0x5c, 0x9c, 0x9e, 0x79, 0x99, 0x25, 0xf1, 0x7e, 80 | 0xf9, 0x79, 0xa9, 0x02, 0xff, 0x61, 0x80, 0x51, 0x88, 0x8b, 0x8b, 0x2d, 0xb8, 0x34, 0x39, 0xb5, 81 | 0xb8, 0x58, 0x80, 0x41, 0x88, 0x9f, 0x8b, 0x3b, 0x34, 0xcf, 0x3b, 0x2f, 0xbf, 0x3c, 0x3e, 0xb4, 82 | 0x38, 0xb5, 0x48, 0x80, 0x51, 0x48, 0x94, 0x4b, 0xd0, 0x37, 0xb3, 0x38, 0x37, 0xb1, 0x24, 0x39, 83 | 0x23, 0x3e, 0x20, 0xb1, 0xb8, 0xb8, 0x3c, 0xbf, 0x28, 0x45, 0x80, 0x09, 0x10, 0x00, 0x00, 0xff, 84 | 0xff, 0x46, 0x65, 0x90, 0x6e, 0x6d, 0x00, 0x00, 0x00, 85 | } 86 | -------------------------------------------------------------------------------- /src/msg_proto/frontend.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: frontend.proto 3 | // DO NOT EDIT! 4 | 5 | package msg_proto 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | type Token struct { 17 | Sid *string `protobuf:"bytes,1,req,name=sid" json:"sid,omitempty"` 18 | Ip *string `protobuf:"bytes,2,req,name=ip" json:"ip,omitempty"` 19 | Port *string `protobuf:"bytes,3,req,name=port" json:"port,omitempty"` 20 | ConnTime *int64 `protobuf:"varint,4,req,name=conn_time" json:"conn_time,omitempty"` 21 | Pid *string `protobuf:"bytes,5,req,name=pid" json:"pid,omitempty"` 22 | XXX_unrecognized []byte `json:"-"` 23 | } 24 | 25 | func (m *Token) Reset() { *m = Token{} } 26 | func (m *Token) String() string { return proto.CompactTextString(m) } 27 | func (*Token) ProtoMessage() {} 28 | func (*Token) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } 29 | 30 | func (m *Token) GetSid() string { 31 | if m != nil && m.Sid != nil { 32 | return *m.Sid 33 | } 34 | return "" 35 | } 36 | 37 | func (m *Token) GetIp() string { 38 | if m != nil && m.Ip != nil { 39 | return *m.Ip 40 | } 41 | return "" 42 | } 43 | 44 | func (m *Token) GetPort() string { 45 | if m != nil && m.Port != nil { 46 | return *m.Port 47 | } 48 | return "" 49 | } 50 | 51 | func (m *Token) GetConnTime() int64 { 52 | if m != nil && m.ConnTime != nil { 53 | return *m.ConnTime 54 | } 55 | return 0 56 | } 57 | 58 | func (m *Token) GetPid() string { 59 | if m != nil && m.Pid != nil { 60 | return *m.Pid 61 | } 62 | return "" 63 | } 64 | 65 | func init() { 66 | proto.RegisterType((*Token)(nil), "msg_proto.Token") 67 | } 68 | 69 | var fileDescriptor1 = []byte{ 70 | // 115 bytes of a gzipped FileDescriptorProto 71 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x2b, 0xca, 0xcf, 72 | 0x2b, 0x49, 0xcd, 0x4b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xcc, 0x2d, 0x4e, 0x8f, 73 | 0x07, 0x33, 0x95, 0xfc, 0xb8, 0x58, 0x43, 0xf2, 0xb3, 0x53, 0xf3, 0x84, 0xb8, 0xb9, 0x98, 0x8b, 74 | 0x33, 0x53, 0x24, 0x18, 0x15, 0x98, 0x34, 0x38, 0x85, 0xb8, 0xb8, 0x98, 0x32, 0x0b, 0x24, 0x98, 75 | 0xc0, 0x6c, 0x1e, 0x2e, 0x96, 0x82, 0xfc, 0xa2, 0x12, 0x09, 0x66, 0x30, 0x4f, 0x90, 0x8b, 0x33, 76 | 0x39, 0x3f, 0x2f, 0x2f, 0xbe, 0x24, 0x33, 0x37, 0x55, 0x82, 0x05, 0x28, 0xc4, 0x0c, 0xd2, 0x59, 77 | 0x00, 0xd4, 0xc9, 0x0a, 0x92, 0x07, 0x04, 0x00, 0x00, 0xff, 0xff, 0x30, 0x22, 0xb8, 0xb9, 0x6b, 78 | 0x00, 0x00, 0x00, 79 | } 80 | -------------------------------------------------------------------------------- /src/msg_proto/gate.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: gate.proto 3 | // DO NOT EDIT! 4 | 5 | package msg_proto 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | type RequestLogin struct { 17 | Username *string `protobuf:"bytes,1,req,name=username" json:"username,omitempty"` 18 | Password *string `protobuf:"bytes,2,req,name=password" json:"password,omitempty"` 19 | XXX_unrecognized []byte `json:"-"` 20 | } 21 | 22 | func (m *RequestLogin) Reset() { *m = RequestLogin{} } 23 | func (m *RequestLogin) String() string { return proto.CompactTextString(m) } 24 | func (*RequestLogin) ProtoMessage() {} 25 | func (*RequestLogin) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } 26 | 27 | func (m *RequestLogin) GetUsername() string { 28 | if m != nil && m.Username != nil { 29 | return *m.Username 30 | } 31 | return "" 32 | } 33 | 34 | func (m *RequestLogin) GetPassword() string { 35 | if m != nil && m.Password != nil { 36 | return *m.Password 37 | } 38 | return "" 39 | } 40 | 41 | func init() { 42 | proto.RegisterType((*RequestLogin)(nil), "msg_proto.RequestLogin") 43 | } 44 | 45 | var fileDescriptor2 = []byte{ 46 | // 92 bytes of a gzipped FileDescriptorProto 47 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x4f, 0x2c, 0x49, 48 | 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xcc, 0x2d, 0x4e, 0x8f, 0x07, 0x33, 0x95, 0x8c, 49 | 0xb8, 0x78, 0x82, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x7c, 0xf2, 0xd3, 0x33, 0xf3, 0x84, 0x04, 50 | 0xb8, 0x38, 0x4a, 0x8b, 0x53, 0x8b, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18, 0x15, 0x98, 0x34, 0x38, 51 | 0x41, 0x22, 0x05, 0x89, 0xc5, 0xc5, 0xe5, 0xf9, 0x45, 0x29, 0x12, 0x4c, 0x20, 0x11, 0x40, 0x00, 52 | 0x00, 0x00, 0xff, 0xff, 0x62, 0xc2, 0x10, 0x83, 0x4b, 0x00, 0x00, 0x00, 53 | } 54 | -------------------------------------------------------------------------------- /src/msg_proto/msgcmd.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: msgcmd.proto 3 | // DO NOT EDIT! 4 | 5 | package msg_proto 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | type MsgCmd int32 17 | 18 | const ( 19 | MsgCmd_None MsgCmd = 0 20 | MsgCmd_CmdResult_S MsgCmd = 1 21 | MsgCmd_RequestLogin_C MsgCmd = 2 22 | MsgCmd_LoginToken_S MsgCmd = 3 23 | ) 24 | 25 | var MsgCmd_name = map[int32]string{ 26 | 0: "None", 27 | 1: "CmdResult_S", 28 | 2: "RequestLogin_C", 29 | 3: "LoginToken_S", 30 | } 31 | var MsgCmd_value = map[string]int32{ 32 | "None": 0, 33 | "CmdResult_S": 1, 34 | "RequestLogin_C": 2, 35 | "LoginToken_S": 3, 36 | } 37 | 38 | func (x MsgCmd) Enum() *MsgCmd { 39 | p := new(MsgCmd) 40 | *p = x 41 | return p 42 | } 43 | func (x MsgCmd) String() string { 44 | return proto.EnumName(MsgCmd_name, int32(x)) 45 | } 46 | func (x *MsgCmd) UnmarshalJSON(data []byte) error { 47 | value, err := proto.UnmarshalJSONEnum(MsgCmd_value, data, "MsgCmd") 48 | if err != nil { 49 | return err 50 | } 51 | *x = MsgCmd(value) 52 | return nil 53 | } 54 | func (MsgCmd) EnumDescriptor() ([]byte, []int) { return fileDescriptor3, []int{0} } 55 | 56 | func init() { 57 | proto.RegisterEnum("msg_proto.MsgCmd", MsgCmd_name, MsgCmd_value) 58 | } 59 | 60 | var fileDescriptor3 = []byte{ 61 | // 114 bytes of a gzipped FileDescriptorProto 62 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x2d, 0x4e, 0x4f, 63 | 0xce, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x04, 0xf2, 0xe2, 0xc1, 0x4c, 0x2d, 64 | 0x4f, 0x2e, 0x36, 0xdf, 0xe2, 0x74, 0xe7, 0xdc, 0x14, 0x21, 0x0e, 0x2e, 0x16, 0xbf, 0xfc, 0xbc, 65 | 0x54, 0x01, 0x06, 0x21, 0x7e, 0x2e, 0x6e, 0xa0, 0x40, 0x50, 0x6a, 0x71, 0x69, 0x4e, 0x49, 0x7c, 66 | 0xb0, 0x00, 0xa3, 0x90, 0x10, 0x17, 0x5f, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x4f, 0x7e, 67 | 0x7a, 0x66, 0x5e, 0xbc, 0xb3, 0x00, 0x93, 0x90, 0x00, 0x17, 0x0f, 0x98, 0x13, 0x92, 0x9f, 0x9d, 68 | 0x9a, 0x07, 0x54, 0xc5, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x90, 0x51, 0xd7, 0x5a, 0x64, 0x00, 69 | 0x00, 0x00, 70 | } 71 | -------------------------------------------------------------------------------- /src/msg_proto/result.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: result.proto 3 | // DO NOT EDIT! 4 | 5 | package msg_proto 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | type CmdResult struct { 17 | ErrorCode *Error `protobuf:"varint,1,req,name=error_code,enum=msg_proto.Error" json:"error_code,omitempty"` 18 | XXX_unrecognized []byte `json:"-"` 19 | } 20 | 21 | func (m *CmdResult) Reset() { *m = CmdResult{} } 22 | func (m *CmdResult) String() string { return proto.CompactTextString(m) } 23 | func (*CmdResult) ProtoMessage() {} 24 | func (*CmdResult) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} } 25 | 26 | func (m *CmdResult) GetErrorCode() Error { 27 | if m != nil && m.ErrorCode != nil { 28 | return *m.ErrorCode 29 | } 30 | return Error_Init_None 31 | } 32 | 33 | func init() { 34 | proto.RegisterType((*CmdResult)(nil), "msg_proto.CmdResult") 35 | } 36 | 37 | var fileDescriptor4 = []byte{ 38 | // 90 bytes of a gzipped FileDescriptorProto 39 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x4a, 0x2d, 0x2e, 40 | 0xcd, 0x29, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0xcc, 0x2d, 0x4e, 0x8f, 0x07, 0x33, 41 | 0xa5, 0xb8, 0x53, 0x8b, 0x8a, 0xf2, 0x8b, 0x20, 0xe2, 0x4a, 0x86, 0x5c, 0x9c, 0xce, 0xb9, 0x29, 42 | 0x41, 0x60, 0xa5, 0x42, 0x2a, 0x5c, 0x5c, 0x60, 0xb9, 0xf8, 0xe4, 0xfc, 0x94, 0x54, 0x09, 0x46, 43 | 0x05, 0x26, 0x0d, 0x3e, 0x23, 0x01, 0x3d, 0xb8, 0x4e, 0x3d, 0x57, 0x90, 0x24, 0x20, 0x00, 0x00, 44 | 0xff, 0xff, 0x54, 0xff, 0xda, 0xc2, 0x59, 0x00, 0x00, 0x00, 45 | } 46 | --------------------------------------------------------------------------------