内容简介:大家好,我是彬哥,本节给大家讲下LollipopGov1.0.20190102版本游戏服务器globla服务器,抛砖引玉了,主要是针对Go语言游戏服务器Global服务器处理。每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!
大家好,我是彬哥,本节给大家讲下LollipopGov1.0.20190102版本游戏服务器globla服务器,抛砖引玉了,主要是针对 Go 语言游戏服务器Global服务器处理。
package main import ( "LollipopGo/LollipopGo/conf" "LollipopGo/LollipopGo/error" "LollipopGo/LollipopGo/log" "LollipopGo/LollipopGo/match" "Proto" "Proto/Proto2" "flag" "fmt" "net/rpc" "net/rpc/jsonrpc" "strings" "time" "LollipopGo/LollipopGo/util" "LollipopGo/ReadCSV" "LollipopGo/LollipopGo/player" "code.google.com/p/go.net/websocket" ) /* 匹配、活动服务器 1 匹配玩家活动 */ var addrG = flag.String("addrG", "127.0.0.1:8888", "http service address") var Conn *websocket.Conn var ConnRPC *rpc.Client func init() { if !initGateWayNet() { fmt.Println("链接 gateway server 失败!") return } fmt.Println("链接 gateway server 成功!") initNetRPC() return } func initNetRPC() { client, err := jsonrpc.Dial("tcp", service) if err != nil { log.Debug("dial error:", err) //panic("dial RPC Servre error") return } ConnRPC = client } func initGateWayNet() bool { fmt.Println("用户客户端客户端模拟!") url := "ws://" + *addrG + "/GolangLtd" conn, err := websocket.Dial(url, "", "test://golang/") if err != nil { fmt.Println("err:", err.Error()) return false } Conn = conn go GameServerReceiveG(Conn) initConn(Conn) return true } // 处理数据 func GameServerReceiveG(ws *websocket.Conn) { for { var content string err := websocket.Message.Receive(ws, &content) if err != nil { fmt.Println(err.Error()) continue } fmt.Println(strings.Trim("", "\"")) fmt.Println(content) content = strings.Replace(content, "\"", "", -1) contentstr, errr := base64Decode([]byte(content)) if errr != nil { fmt.Println(errr) continue } go SyncMeassgeFunG(string(contentstr)) } } // 链接分发 处理 func SyncMeassgeFunG(content string) { var r Requestbody r.req = content if ProtocolData, err := r.Json2map(); err == nil { HandleCltProtocolG(ProtocolData["Protocol"], ProtocolData["Protocol2"], ProtocolData) } else { log.Debug("解析失败:", err.Error()) } } // 主协议处理 func HandleCltProtocolG(protocol interface{}, protocol2 interface{}, ProtocolData map[string]interface{}) { // defer func() { // 必须要先声明defer,否则不能捕获到panic异常 // if err := recover(); err != nil { // strerr := fmt.Sprintf("%s", err) // //发消息给客户端 // ErrorST := Proto2.G_Error_All{ // Protocol: Proto.G_Error_Proto, // 主协议 // Protocol2: Proto2.G_Error_All_Proto, // 子协议 // ErrCode: "80006", // ErrMsg: "亲,您发的数据的格式不对!" + strerr, // } // // 发送给玩家数据 // fmt.Println("Global server的主协议!!!", ErrorST) // } // }() // 协议处理 switch protocol { case float64(Proto.G_GameGlobal_Proto): { // Global Server 主要协议处理 fmt.Println("Global server 主协议!!!") HandleCltProtocol2Glogbal(protocol2, ProtocolData) } default: panic("主协议:不存在!!!") } return } // 子协议的处理 func HandleCltProtocol2Glogbal(protocol2 interface{}, ProtocolData map[string]interface{}) { switch protocol2 { case float64(Proto2.GW2G_ConnServerProto2): { // 网关返回数据 fmt.Println("gateway server 返回给global server 数据信息!!!") } case float64(Proto2.G2GW_PlayerEntryHallProto2): { G2GW_PlayerEntryHallProto2Fucn(Conn, ProtocolData) } case float64(Proto2.G2GW_PlayerMatchGameProto2): { fmt.Println("玩家请求玩家匹配!") G2GW_PlayerMatchGameProto2Fucn(Conn, ProtocolData) } case float64(Proto2.GW2G_PlayerQuitMatchGameProto2): { fmt.Println("玩家主动退出匹配!") G2GW_PlayerQuitMatchGameProto2Fucn(Conn, ProtocolData) } default: panic("子协议:不存在!!!") } return } // 玩家主动退出匹配 func G2GW_PlayerQuitMatchGameProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) { if ProtocolData["OpenID"] == nil { panic("玩家主动退出匹配!") return } StrOpenID := ProtocolData["OpenID"].(string) // 玩家主动退出 match.SetQuitMatch(StrOpenID) // 发送消息 data_send := &Proto2.G2GW_PlayerQuitMatchGame{ Protocol: Proto.G_GameGlobal_Proto, Protocol2: Proto2.G2GW_PlayerQuitMatchGameProto2, OpenID: StrOpenID, ResultID: 0, } PlayerSendToServer(conn, data_send) return } // 玩家匹配 func G2GW_PlayerMatchGameProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) { if ProtocolData["OpenID"] == nil || ProtocolData["RoomID"] == nil || ProtocolData["Itype"] == nil { panic("选择游戏对战类型协议参数错误!") return } StrOpenID := ProtocolData["OpenID"].(string) StrRoomID := ProtocolData["RoomID"].(string) // 匹配数据 StrItype := ProtocolData["Itype"].(string) // 1 是正常匹配 2 是快速匹配 // 数据 data_send := &Proto2.GW2G_PlayerMatchGame{ Protocol: Proto.G_GameGlobal_Proto, // 游戏主要协议 Protocol2: Proto2.GW2G_PlayerMatchGameProto2, OpenID: StrOpenID, // 玩家唯一标识 // RoomUID: 0, // MatchPlayer: nil, // ChessBoard: {{}, {}, {}, {}}, ResultID: 0, } if match.GetMatchQueue(StrOpenID) { data_send.ResultID = Error.IsMatch PlayerSendToServer(conn, data_send) return } match.SetMatchQueue(StrOpenID) if StrItype == "2" { //快速匹配 PlayerSendToServer(conn, data_send) return } data := conf.RoomListDatabak[StrRoomID] fmt.Println("针对某房间ID去获取,相应的数据的", conf.RoomListDatabak, data.NeedLev, StrRoomID) dataplayer := DB_Save_RoleSTBak(StrOpenID) match.Putdata(dataplayer) s := string([]byte(data.NeedLev)[2:]) if util.Str2int_LollipopGo(s) > dataplayer.Lev { data_send.ResultID = Error.Lev_lack PlayerSendToServer(conn, data_send) return } else if util.Str2int_LollipopGo(data.NeedPiece) > dataplayer.CoinNum { data_send.ResultID = Error.Coin_lack PlayerSendToServer(conn, data_send) return } if len(match.MatchData) > 1 { dar := <-match.MatchData_Chan data_send.MatchPlayer = dar fmt.Println(data_send) PlayerSendToServer(conn, data_send) match.DelMatchQueue(StrOpenID) } else { go PlayerMatchTime(conn, StrOpenID, data_send) } return } func PlayerMatchTime(conn *websocket.Conn, OpenID string, data_send *Proto2.GW2G_PlayerMatchGame) { icount := 0 for { select { case <-time.After(match.PlaterMatchSpeed): { fmt.Println(icount) if icount >= 30 { PlayerSendToServer(conn, data_send) return } if len(match.MatchData_Chan) > 1 { dar := <-match.MatchData_Chan data_send.MatchPlayer = dar fmt.Println(data_send) PlayerSendToServer(conn, data_send) match.DelMatchQueue(OpenID) return } icount++ } } } } // 保存数据都DB 人物信息 func DB_Save_RoleSTBak(openid string) *player.PlayerSt { args := player.PlayerSt{ OpenID: openid, } var reply *player.PlayerSt // 异步调用【结构的方法】 if ConnRPC != nil { // ConnRPC.Call("Arith.GetPlayerST2DB", args, &reply) 同步调用 divCall := ConnRPC.Go("Arith.GetPlayerST2DB", args, &reply, nil) replyCall := <-divCall.Done _ = replyCall.Reply } else { fmt.Println("ConnRPC == nil") } return reply } func G2GW_PlayerEntryHallProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) { StrUID := ProtocolData["UID"].(string) StrOpenID := ProtocolData["OpenID"].(string) StrPlayerName := ProtocolData["PlayerName"].(string) StrHeadUrl := ProtocolData["HeadUrl"].(string) StrSex := ProtocolData["Sex"].(string) StrConstellation := ProtocolData["Constellation"].(string) StrPlayerSchool := ProtocolData["PlayerSchool"].(string) StrToken := ProtocolData["Token"].(string) _ = StrToken // 获取在线人数 ddd := make(map[string]interface{}) csv.M_CSV.LollipopGo_RLockRange(ddd) // 查询数据库,找出游戏服务器的uid信息 // 返回的数据操作 datadb := DB_Save_RoleST(StrUID, StrPlayerName, StrHeadUrl, StrPlayerSchool, StrSex, StrConstellation, 0, 0, 2000, 0, 0) fmt.Println("--------------------------:", datadb) // 个人数据 personalmap := make(map[string]*player.PlayerSt) personalmap["1"] = &datadb _ = personalmap["1"].OpenID // 组装数据 data := &Proto2.GW2G_PlayerEntryHall{ Protocol: Proto.G_GameGlobal_Proto, // 游戏主要协议 Protocol2: Proto2.GW2G_PlayerEntryHallProto2, OpenID: StrOpenID, PlayerName: StrPlayerName, HeadUrl: StrHeadUrl, Constellation: StrConstellation, Sex: StrSex, GamePlayerNum: ddd, RacePlayerNum: nil, Personal: personalmap, DefaultMsg: nil, DefaultAward: nil, } fmt.Println(data) PlayerSendToServer(conn, data) // 保存玩家的数据 -- 主要是为了 return } // 保存数据都DB 人物信息 func DB_Save_RoleST(uid, strname, HeadURL, StrPlayerSchool, Sex, Constellation string, Lev, HallExp, CoinNum, MasonryNum, MCard int) player.PlayerSt { args := player.PlayerSt{ UID: util.Str2int_LollipopGo(uid), VIP_Lev: 0, Name: strname, HeadURL: HeadURL, Sex: Sex, PlayerSchool: StrPlayerSchool, Lev: Lev, HallExp: HallExp, CoinNum: CoinNum, MasonryNum: MasonryNum, MCard: MCard, Constellation: Constellation, OpenID: util.MD5_LollipopGO(uid), } var reply player.PlayerSt // 异步调用【结构的方法】 if ConnRPC != nil { // ConnRPC.Call("Arith.SavePlayerST2DB", args, &reply) 同步调用 divCall := ConnRPC.Go("Arith.SavePlayerST2DB", args, &reply, nil) replyCall := <-divCall.Done _ = replyCall.Reply } else { fmt.Println("ConnRPC == nil") } return reply } func initConn(conn *websocket.Conn) { data := &Proto2.G2GW_ConnServer{ Protocol: Proto.G_GameGlobal_Proto, Protocol2: Proto2.G2GW_ConnServerProto2, ServerID: util.MD5_LollipopGO("8894" + "Global server"), } PlayerSendToServer(conn, data) return }
每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!
社区交流群:221273219
Golang语言社区论坛 :
LollipopGo游戏服务器地址:
https://github.com/Golangltd/LollipopGo
社区视频课程课件GIT地址:
https://github.com/Golangltd/codeclassGolang语言社区
以上所述就是小编给大家介绍的《LollipopGo开源游戏服务器框架--global服务器源码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Web服务器、应用程序服务器、HTTP服务器区别
- 远离服务器宕机 腾讯WeTest推出服务器深度性能测试服务
- FTP服务器和Web服务器知多少
- 无服务器云安全:如何保护无服务器计算
- 服务器完整搭建jupyter 科学环境服务
- [应用服务器]掌握Tomcat应用服务器只需一分钟
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。