codecamp

xingo 单进程服务器入门教程

推荐项目目录结构:

.
├── api                                             用户自定义协议
│   └── test_api.go
├── client_walk.go                             自动化游戏全逻辑测试脚本
├── conf                                          
│   └── server.json                             服务器全局配置
├── core                                           游戏核心逻辑/各种游戏玩法,活动相关逻辑放到这儿
│   ├── aoi.go
│   ├── player.go
│   └── worldmgr.go
├── log                                             默认日志文件存放路径/日志可按照时间和大小切割
│   ├── server.log
│   ├── server.log.2016-12-20
│   ├── server.log.2016-12-26
├── pb                                              消息定义
│   ├── msg.pb.go                              
│   └── msg.proto
├── README.md
├── server.go                                    服务器主逻辑


推荐clone demo项目到本地:

git clone https://git.oschina.net/viphxin/xingo_demo.git

配置服务器

vim conf/server.json

{
   "TcpPort": 8999,//监听端口
   "StepPerMs": 2000,//demo逻辑配置,非通用配置项
   "PoolSize": 5,    //工作队列数
   "IsUsePool": true,//是否使用工作队列
   "LogLevel": 1,    //日志级别 0 ALL 1 DEBUG 2 INFO 3 WARN 4 ERROR 5 FATAL 6 OFF
   "MaxConn": 2000   //支持最大连接数
}
google protobuf消息定义:

message Talk{
   string Content=1;
}
定义一个测试接口api,实现功能世界聊天(广播每个链接发过来的talk消息):

导入xingo

import (
       "xingo_demo/pb"
       "xingo_demo/core"
       "github.com/golang/protobuf/proto"
       "github.com/viphxin/xingo/fnet"
       "github.com/viphxin/xingo/logger"
       "fmt"
)
定义api接口:

type TestRouter struct {
}

/*
ping test
*/
func (this *TestRouter) Api_0(request *fnet.PkgAll) {
       logger.Debug("call Api_0")
       // request.Fconn.SendBuff(0, nil)
       packdata, err := fnet.DefaultDataPack.Pack(0, nil)
       if err == nil{
              request.Fconn.Send(packdata)
       }else{
              logger.Error("pack data error")
       }
}

/*
世界聊天
 */
func (this *TestRouter) Api_2(request *fnet.PkgAll) {
       msg := &pb.Talk{}
       err := proto.Unmarshal(request.Pdata.Data, msg)//解析Talk消息
       if err == nil {
              logger.Debug(fmt.Sprintf("user talk: content: %s.", msg.Content))
              pid, err1 := request.Fconn.GetProperty("pid")
              if err1 == nil{
                     p, _ := core.WorldMgrObj.GetPlayer(pid.(int32))
                     p.Talk(msg.Content)//广播
              }else{
                     logger.Error(err1)
                     request.Fconn.LostConnection()
              }

       } else {
              logger.Error(err)
              request.Fconn.LostConnection()
       }
}

实现自己的xingo server

package main

import (
       "fmt"
       "github.com/viphxin/xingo/fserver"
       "github.com/viphxin/xingo/iface"
       "github.com/viphxin/xingo/logger"
       "github.com/viphxin/xingo/utils"
       "xingo_demo/api"
       "xingo_demo/core"
       "os"
       "os/signal"
)

func DoConnectionMade(fconn iface.Iconnection) {
       logger.Debug("111111111111111111111111")
       p, _ := core.WorldMgrObj.AddPlayer(fconn)
       fconn.SetProperty("pid", p.Pid)
}

func DoConnectionLost(fconn iface.Iconnection) {
       logger.Debug("222222222222222222222222")
       pid, _ := fconn.GetProperty("pid")
       p, _ := core.WorldMgrObj.GetPlayer(pid.(int32))
       //移除玩家
       core.WorldMgrObj.RemovePlayer(pid.(int32))
       //消失在地图
       p.LostConnection()
}

func main() {
       s := fserver.NewServer()
       //add api ---------------start
       TestRouterObj := &api.TestRouter{}
       s.AddRouter(TestRouterObj)//注册接口api
       //add api ---------------end
       //regest callback
       utils.GlobalObject.OnConnectioned = DoConnectionMade//绑定链接建立处理函数
       utils.GlobalObject.OnClosed = DoConnectionLost//绑定链接丢失处理函数

       s.Start()//开启服务器
       // close
       c := make(chan os.Signal, 1)
       signal.Notify(c, os.Interrupt, os.Kill)
       sig := <-c
       fmt.Println("=======", sig)
       s.Stop()
}

xingo代码结构
xingo 集群服务器入门教程
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }