Leaf游戏框架—玩家登陆协议定义

首先 我们需要增加玩家注册、登陆的协议,消息结构定义在server\msg\msg.go中,但是为了便于查找建议单独建立文件 例如 如下图 建立目录:server\msg\protocolfile\protocol.go

protocol.go 内容

  1. package Protocol
  2. // 用户登陆协议
  3. type UserLogin struct {
  4. LoginName string // 用户名
  5. LoginPW string // 密码
  6. }
  7. // 注册协议
  8. type UserRegister struct {
  9. LoginName string // 用户名
  10. LoginPW string // 密码
  11. // Mobi string // 手机号
  12. // Email string // 邮箱
  13. }
  14. // 玩家的临时结构
  15. // 玩家有角色的情况
  16. type UserST struct {
  17. UID string // 账号ID
  18. ServerID string // 服务器ID
  19. RoleUID string // 角色UID
  20. RoleName string // 角色名字
  21. RoleLev string // 角色等级
  22. Coin string // 金币
  23. // 其他的暂时不做定义
  24. }

登陆路由配置

路由配置方式请参照前几节文章,本节及后面只是概括
路径:server\gate\router.go

router.go :

  1. package gate
  2. import (
  3. _ "server/game"
  4. "server/login"
  5. "server/msg"
  6. "server/msg/protocolfile"
  7. )
  8. func init() {
  9. msg.Processor.SetRouter(&Protocol.UserLogin{}, login.ChanRPC)
  10. }

注册消息
路径:server\msg\msg.go
msg.go:

  1. package msg
  2. import (
  3. "server/msg/protocolfile"
  4. "github.com/name5566/leaf/network"
  5. "github.com/name5566/leaf/network/json"
  6. )
  7. var Processorbak network.Processor
  8. // 使用默认的 JSON 消息处理器(默认还提供了 protobuf 消息处理器)
  9. var Processor = json.NewProcessor()
  10. func init() {
  11. // 这里我们注册了一个 JSON 消息 Test
  12. Processor.Register(&Protocol.UserLogin{})
  13. }

以上配置完成后,消息注册及路由配置就OK了,总结下 如下:
1 msg.go 消息注册使用
2 protocol.go 消息定义

leaf游戏服务器处理玩家登陆逻辑

文件位置:
server\login\internal\module.go
注:此节不链接MongoDB

module.go

  1. package internal
  2. import (
  3. "reflect"
  4. "server/msg/protocolfile"
  5. "github.com/name5566/leaf/gate"
  6. "github.com/name5566/leaf/log"
  7. )
  8. func handleMsg(m interface{}, h interface{}) {
  9. skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
  10. }
  11. func init() {
  12. // 向当前模块(login 模块)注册 Protocol.UserLogin 消息的消息处理函数 handleTest
  13. handleMsg(&Protocol.UserLogin{}, handleTest)
  14. }
  15. // 消息处理
  16. func handleTest(args []interface{}) {
  17. // 收到的 Test 消息
  18. m := args[0].(*Protocol.UserLogin)
  19. // 消息的发送者
  20. a := args[1].(gate.Agent)
  21. // 1 查询数据库--判断用户是不是合法
  22. // 2 如果数据库返回查询正确--保存到缓存或者内存
  23. // 输出收到的消息的内容
  24. log.Debug("Test login %v", m.LoginName)
  25. // 给发送者回应一个 Test 消息
  26. a.WriteMsg(&Protocol.UserLogin{
  27. LoginName: "client",
  28. })
  29. }

H5客户端实现

index.html:

  1. <head>
  2. <meta charset="utf-8" />
  3. <title></title>
  4. </head>
  5. <body>
  6. <h3 style="color: cornflowerblue;">Golang语言社区(www.Golang.Ltd)</h3> 发送数据: <input type='text' id='name' value="Leaf测试">
  7. <input type="submit" onclick="login()" />
  8. </body>
  9. <script>
  10. var wsUri = "ws://127.0.0.1:8889/?{'new':3}";
  11. var json;
  12. function login() {
  13. var Data = {
  14. LoginName: "Golang.Ltd",
  15. LoginPW: "123456",
  16. };
  17. var json = {
  18. UserLogin:Data
  19. }
  20. var goServerJson = JSON.stringify(json);
  21. wsUri = wsUri;
  22. console.log(wsUri);
  23. doSend(goServerJson);
  24. }
  25. var output;
  26. var websocket1;
  27. function init() {
  28. output = document.getElementById("output");
  29. testWebSocket();
  30. }
  31. function testWebSocket() {
  32. console.log(wsUri)
  33. websocket1 = new WebSocket(wsUri);
  34. websocket1.onopen = function(evt) {
  35. onOpen(evt)
  36. };
  37. websocket1.onclose = function(evt) {
  38. onClose(evt)
  39. };
  40. websocket1.onmessage = function(evt) {
  41. onMessage(evt)
  42. };
  43. websocket1.onerror = function(evt) {
  44. onError(evt)
  45. };
  46. }
  47. function onOpen(evt) {
  48. console.log("CONNECTED");
  49. }
  50. function onClose(evt) {
  51. console.log("DISCONNECTED");
  52. }
  53. function onMessage(evt) {
  54. var data = evt.data;
  55. console.log("data=" + data);
  56. }
  57. function onError(evt) {
  58. console.log(evt.data);
  59. }
  60. function doSend(message) {
  61. console.log(message);
  62. websocket1.send(message);
  63. }
  64. window.addEventListener("load", init, false);
  65. </script>

页面截图:
golang leaf 游戏玩家注册、登录 - 图1

简单说明下,H5的部分代码
1 链接端口为什么是8889 ?
原因是我们在leaf架构中配置的是8889
文件位置:
server\conf\server.json

server.json

  1. {
  2. "LogLevel": "debug",
  3. "LogPath": "",
  4. "WSAddr": "127.0.0.1:8889",
  5. "CertFile": "",
  6. "KeyFile": "",
  7. "TCPAddr": "127.0.0.1:8888",
  8. "MaxConnNum": 20000,
  9. "ConsolePort": 8012,
  10. "ProfilePath": ""
  11. }

H5测试链接Leaf服务器

Leaf服务器接到的测试结果:
golang leaf 游戏玩家注册、登录 - 图2

H5接收到Leaf服务器发回数据测试结果:
golang leaf 游戏玩家注册、登录 - 图3

H5客户端处理Leaf返回消息处理

  1. function onMessage(evt) {
  2. console.log(evt);
  3. var filrReader = new FileReader();
  4. filrReader.onload = function() {
  5. var arrayBuffer = this.result;
  6. var decoder = new TextDecoder('utf-8')
  7. var json = JSON.parse(decoder.decode(new DataView(arrayBuffer)));
  8. console.log(json);
  9. };
  10. filrReader.readAsArrayBuffer(evt.data);
  11. };

Leaf服务器返回给H5的JSON消息结构
文件位置:server\login\internal\handler.go

  1. package internal
  2. import (
  3. "reflect"
  4. "server/msg/protocolfile"
  5. "github.com/name5566/leaf/gate"
  6. "github.com/name5566/leaf/log"
  7. )
  8. func handleMsg(m interface{}, h interface{}) {
  9. skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
  10. }
  11. func init() {
  12. // 向当前模块(login 模块)注册 Protocol.UserLogin 消息的消息处理函数 handleTest
  13. handleMsg(&Protocol.UserLogin{}, handleTest)
  14. }
  15. // 消息处理
  16. func handleTest(args []interface{}) {
  17. // 收到的 Test 消息
  18. m := args[0].(*Protocol.UserLogin)
  19. // 消息的发送者
  20. a := args[1].(gate.Agent)
  21. // 1 查询数据库--判断用户是不是合法
  22. // 2 如果数据库返回查询正确--保存到缓存或者内存
  23. // 输出收到的消息的内容
  24. log.Debug("Test login %v", m.LoginName)
  25. log.Debug("---------", Protocol.UserLogin{
  26. LoginName: "client",
  27. })
  28. dd := &Protocol.UserLogin{
  29. LoginName: "client",
  30. LoginPW: "client",
  31. }
  32. //a.PlaySendMessage(dd)
  33. a.WriteMsg(dd)
  34. }

测试结果

H5网页显示结果 如下:
golang leaf 游戏玩家注册、登录 - 图4


golang leaf 游戏玩家注册、登录 - 图5