内容简介:大家好,我是彬哥,本节给大家讲下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) } case float64(Proto2.GW2G_GetPlayerEmailListProto2): { fmt.Println("获取玩家邮件列表!") G2GW_PlayerGetPlayerEmailListProto2Fucn(Conn, ProtocolData) } case float64(Proto2.GW2G_ReadOrDelPlayerEmailProto2): { fmt.Println("玩家邮件列表读取!") G2GW_PlayerReadOrDelPlayerEmailProto2Fucn(Conn, ProtocolData) } default: panic("子协议:不存在!!!") } return } func G2GW_PlayerReadOrDelPlayerEmailProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) { if ProtocolData["OpenID"] == nil { panic("读取邮件错误!") } StrOpenID := ProtocolData["OpenID"].(string) iItype := int(ProtocolData["Itype"].(float64)) iEmailID := int(ProtocolData["EmailID"].(float64)) data_send := &Proto2.G2GW_ReadOrDelPlayerEmail{ Protocol: Proto.G_GameGlobal_Proto, Protocol2: Proto2.G2GW_ReadOrDelPlayerEmailProto2, OpenID: StrOpenID, Itype: iItype, } // 1:读取打开,2:删除,3:领取附件 if iItype == 1 { if EmailDatatmp[iEmailID] == nil { EmailDatatmp[iEmailID].IsOpen = true data_send.Itype = 0 } } else if iItype == 2 { delete(EmailDatatmp, iEmailID) } else if iItype == 3 { EmailDatatmp[iEmailID].IsAdd_ons = true } PlayerSendToServer(conn, data_send) return } //------------------------------------------------------------------------------ var EmailDatatmp map[int]*player.EmailST var ItemListtmp map[int]*player.ItemST var PaoMaDeng map[int]*player.MsgST func init() { EmailDatatmp = make(map[int]*player.EmailST) ItemListtmp = make(map[int]*player.ItemST) PaoMaDeng = make(map[int]*player.MsgST) if true { data := new(player.EmailST) data.ID = 1 data.Name = "测试邮件1" data.Time = int(util.GetNowUnix_LollipopGo()) data.Content = "测试邮件内容1" data.IsAdd_ons = false data.IsOpen = false EmailDatatmp[data.ID] = data } if true { data := new(player.EmailST) data.ID = 2 data.Name = "测试邮件2" data.Time = int(util.GetNowUnix_LollipopGo()) data.Content = "测试邮件内容2" data.IsAdd_ons = false data.IsOpen = false EmailDatatmp[data.ID] = data } if true { data := new(player.EmailST) data.ID = 3 data.Name = "测试邮件3" data.Time = int(util.GetNowUnix_LollipopGo()) data.Content = "测试邮件内容3" data.IsAdd_ons = true data.IsOpen = false if true { dataitem := new(player.ItemST) dataitem.ID = 1 dataitem.Icon = "" dataitem.Name = "M卡" dataitem.Itype = 1 dataitem.Num = 10 ItemListtmp[dataitem.ID] = dataitem } data.ItemList = ItemListtmp EmailDatatmp[data.ID] = data } //-------------------------------------------------------------------------- // DefaultMsg map[string]*player.MsgST // 默认跑马灯消息 if true { data := new(player.MsgST) data.MsgID = 1 data.MsgType = player.MsgType1 data.MsgDesc = "系统消息:充值998,送B站24K纯金哥斯拉" PaoMaDeng[data.MsgID] = data } if true { data := new(player.MsgST) data.MsgID = 2 data.MsgType = player.MsgType2 data.MsgDesc = "恭喜【XXX玩家】在XX比赛中获得xxx奖励" PaoMaDeng[data.MsgID] = data } if true { data := new(player.MsgST) data.MsgID = 3 data.MsgType = player.MsgType3 data.MsgDesc = "恭喜【XXX玩家】在兑换中心成功兑换SSS" PaoMaDeng[data.MsgID] = data } return } //------------------------------------------------------------------------------ func G2GW_PlayerGetPlayerEmailListProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) { if ProtocolData["OpenID"] == nil { panic("获取玩家列表!") } StrOpenID := ProtocolData["OpenID"].(string) data_send := &Proto2.G2GW_GetPlayerEmailList{ Protocol: Proto.G_GameGlobal_Proto, Protocol2: Proto2.G2GW_GetPlayerEmailListProto2, OpenID: StrOpenID, EmailData: EmailDatatmp, } PlayerSendToServer(conn, data_send) 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: PaoMaDeng, DefaultAward: nil, IsNewEmail: true, } if len(EmailDatatmp) == 0 { data.IsNewEmail = false } 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语言社区
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Web服务器、应用程序服务器、HTTP服务器区别
- 远离服务器宕机 腾讯WeTest推出服务器深度性能测试服务
- FTP服务器和Web服务器知多少
- 无服务器云安全:如何保护无服务器计算
- 服务器完整搭建jupyter 科学环境服务
- [应用服务器]掌握Tomcat应用服务器只需一分钟
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Cracking the Coding Interview
Gayle Laakmann McDowell / CareerCup / 2015-7-1 / USD 39.95
Cracking the Coding Interview, 6th Edition is here to help you through this process, teaching you what you need to know and enabling you to perform at your very best. I've coached and interviewed hund......一起来看看 《Cracking the Coding Interview》 这本书的介绍吧!