首页 > 其他分享 >跟炒鸡辣鸡一起学用go写游戏后端

跟炒鸡辣鸡一起学用go写游戏后端

时间:2022-11-03 10:34:53浏览次数:46  
标签:int32 鸡辣鸡 http ROOM fmt go MessageId 学用 GetMsgRegistry


几个月前,把java分布式游戏后端研究了一遍,仿照现成的架构写了两套游戏出来。但是我的脚步并未停下,现在开始研究如何用Go语言搭建游戏后端。

1、设计前后端交互的方式
之前的java我用到了netty+protobuf和前端进行交互,而游戏服务之间采用RPC(远程过程调用)的方式进行通信。netty是java网络编程中一种比较优秀的网络通信框架,采用的是select事件驱动模式,这种轮询的方式尽管有些落后,但是相比于同步NIO的通信方式,性能还是有大幅度的提升。
在go中,一般使用net/http来建立和远程客户端的通信,搭配webSocket来接收并处理远程的请求。一个用net/http来搭建服务器的例程如下:

package main
import (
"fmt"
"net/http"
"log"
)
func HandleIndex(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fmt.Println("PATH: ", r.URL.Path)
fmt.Println("SCHEME: ", r.URL.Scheme)
fmt.Println("METHOD: ", r.Method)
fmt.Println()
fmt.Fprintf(w, "<h1>Index Page</h1>")
}
func main() {
http.HandleFunc("/", HandleIndex)
err := http.ListenAndServe(":8000", nil)
if err != nil {
log.Fatal("ERROR: ", err)
}
}

我把这段代码解析一下:

http.HandleFunc("/", HandleIndex)
//注册处理类,即表示如果收到根目录的请求,就使用HandleIndex这个方法来解决
http.ListenAndServe(":8000", nil)
//服务监听8000端口

​​用go搭建一个demo服务器博客入口​​

2、包net/http中嵌入websocket包的方法:

http.Handle("/xss/", websocket.Server{Handler: s.handleClient, Handshake: nil})

确定了前后端走通过http和websocket之后,可以使用mux包来定义处理路由

//导入方法:
imposrt "github.com/gorilla/mux"
//使用方法:
r := mux.NewRouter()
http.Handle("/", r)

//定义mux
func registerHttpHandlers(r *mux.Router) {
r.HandleFunc("/v123/plat/userInfo", web.WebUserInfoHandler)
r.HandleFunc("/v123/plat/userCharge", web.WebChangeCardHandler)
}
//需要使用路由的时候只需要调用
registerHttpHandlers(r)
//就可以了

除了显式的调用路由处理的方法来预定义处理类,还可以定义数据包的格式来接收和处理前端的请求。首先,定义一个枚举类型来表示消息类型:

const (
MessageId_LOGIN = 1 //登录
MessageId_HEART_BEAT = 2 //心跳
MessageId_RECONNECT = 3 //重连
MessageId_CREATE_ROOM = 4 //创建房间
MessageId_ENTER_ROOM = 5 //进入房间
MessageId_ENTER_ROOM_NOTIFY = 6 //进入房间通知
MessageId_BACK_ROOM = 7 //返回房间信息
MessageId_DISMISS_ROOM_REQ = 8 //解散房间请求
MessageId_DISMISS_ROOM_NOTIFY = 9 //解散请求房间广播
MessageId_DISMISS_ROOM_USER_RESULT = 10 //其他玩家的处理结果
MessageId_DISMISS_ROOM_USER_RESULT_NOTIFY = 11 //其他玩家的处理结果广播
MessageId_DISMISS_ROOM_RESULT_NOTIFY = 12 //解散房间成功通知
MessageId_LEAVE_ROOM = 13 //退出房间
MessageId_LEAVE_ROOM_NOTIFY = 14 //退出房间广播
MessageId_BACK_ROOM_NOTIFY = 15 //返回房间广播
MessageId_START_GAME = 16 //游戏开始
...
)

定义了消息类型之后,就可以来注册处理类了,可以自行设计一个集合,以键值对的方式,将消息类型的枚举值作为key,而处理方法作为value,每次接收到message后可以自动响应出解决的方法。

func registerUserHandlers() {
GetMsgRegistry().RegisterUnLoginMsg(int32(util.MessageId_LOGIN))
GetMsgRegistry().RegisterUnLoginMsg(int32(util.MessageId_WECHAT_LOGIN))
GetMsgRegistry().RegisterUnLoginMsg(int32(util.MessageId_ACCESSTOKEN_LOGIN))
GetMsgRegistry().RegisterMsg(int32(util.MessageId_LOGIN), user.LoginHandler)
GetMsgRegistry().RegisterMsg(int32(util.MessageId_CREATE_ROOM), user.CreateRoomHandler)
GetMsgRegistry().RegisterMsg(int32(util.MessageId_ENTER_ROOM), user.EnterRoomHandler)
GetMsgRegistry().RegisterMsg(int32(util.MessageId_BACK_ROOM), user.BackRoomHandler)
}

然后等到收到前端的请求之后就可以使用类似于

func (registry *MsgRegistry) getHandler(msgId int32) func(msg *server.ClientMsg, sess *server.Session) []byte {
registry.mu.RLock()
defer registry.mu.RUnlock()
fmt.Print(msgId)
fmt.Print("\n")
return registry.registry[msgId]
}

这样的方法取出来。这样设计并接收前端请求的架构就已经搭建好了。


标签:int32,鸡辣鸡,http,ROOM,fmt,go,MessageId,学用,GetMsgRegistry
From: https://blog.51cto.com/u_14196886/5819069

相关文章

  • 跟炒鸡辣鸡一起学用go写游戏后端2
    上回说完了采用何种方式与前端进行交互,这次来说说使用何种形式的数据格式与前端进行交互。也就是通常所说的protocol(协议)。目前,比较主流的是json和xml的方式,不过鉴于游戏......
  • go 常见外部包解析
    go(五)1、gorilla/mux导入:import"github.com/gorilla/mux"gorilla/mux是一个强大的路由,小巧但是稳定高效,不仅可以支持正则路由还可以按照Method,header,host等信息匹配使用示......
  • Django --根据已有表生成ORM模型
    在实际开发中,有些时候可能数据库已经存在了。如果我们用Django来开发一个网站,读职的是之前已经存在的数据库中的数据。那么该如何将模型与数据库中的表映射呢?根据旧的数......
  • 实例034 使用goto语句在数组中搜索指定图书
      usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usi......
  • 数据库设计心得-4班ok_fine_goodnight组
    数据库系统设计心得_ok_fine_goodnight引言首先为什么要设计数据库:当数据库比较复杂(如数据量大,表较多,业务关系复杂)时,我们需要先设计数据库.一个好的数据库设计能保......
  • Orthogonal Quasi-Triangularization
    Theorem.Let \(V\) be a finite-dim'l real ips, and let \(T\) be a linear operator on \(V\). Then there exists an onb \(\beta\) for \(V\)......
  • Springboot使用mongodb遇到问题及解决
    网上看到使用mongodb好像很简单,没有什么问题,可我一用就怎么都连不上,先看看我的配置 在pom.xml中添加依赖 1234<dependency>  <groupId>org.springframew......
  • django中间件以及自定义中间件
    middleware中间件就是在目标和结果之间进行的额外处理过程,在Django中就是request和response之间进行的处理,相对来说实现起来比较简单,但是要注意它是对全局有效的,可以在全......
  • Typora图床上传配置:PicGo+Gitee 不完全指南
    每次写Markdown都要手动传图,再复制链接到Typora里,这样比较繁琐。设置好图床,搭配PicGo,写作时直接剪贴图片到Typora,就能实现自动上传,这样就方便很多。......
  • 协程的简单操作,你都知道哪些?Golang如何实现协程交替打印?
    博主介绍:–我是了凡微信公众号【​​了凡银河系​​】期待你的关注。未来大家一起加油啊~前言对于并发的概念,我们都清楚为了合理利用CPU的执行效率,我们选择当一个事务或......