examples/

directory
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2025 License: MIT

README

Program examples

用easy 实现的 服务端 和客户端样例

Simple

simple

比较简单的源码样例;

这是一个简单的服务端,你可以直接拿它做项目,扩展开发即可。

  • 最基本的easy框架使用
  • 简单的游戏架构,不包含数据层;
  • simple代码以极简化为主,项目扩展要 结构化一些
  • 目录多是空的
simple 目录介绍
--conf // 配置
--controller 控制器也就是解读消息的入口
    --callback 放置一些基本的回调函数,如链接创建,服务平滑关闭等
    --login 登陆模块
    --player 用户玩家
    --store 商铺
    --world 大世界相关
--initialize 初始化,工程启动执行一次;与运行时无关
--lservers 接入easy监听服务 l 是 ```listen``` 当让也可以接入其他的监听服务
--message 消息定义
--models 数据模型,尽量只有数据结构的定义,和基本验证
--services 游戏逻辑存放区域,主要的逻辑都可以放在这里
--vendors 您项目的一些必要基础功能性的包,或者接入第三方包(且这个包需要配置等);// 并非是替代 go mod
    注意:
    go mod 中也有一个verdor 且会产生vendor文件夹
    我们这里的vendors 仅仅是common 通用,基础,标准等的意思
    这里的包之间互相依赖也少,或者说机会是无
    比较大(功能性)的包引入后,总需要配置一些东西,甚至和自己的配置参数相关,那么放在这里改造一下(符合工程写法,结构要求等)就比较合适了
simple_client

明显是simple 对应的客户端测试代码

  • run

nws = the number of websocket connections

ntcp = the number of tcp connections

go build && ./simple_client -nws=1000 -ntcp=0

RPC

我们使用的grpc和etcd,构成了一个完整的服务发现模式。可以轻松实现稳定分层,分布式架构的服务。

代码中出现的namespace 与 scheme 是同一个概念。

这介绍的简单教程,详细运行代码可以看example/rpc 的源码。

ETCD with docker

helloworld

这个子package 是官方的一个 接口定义的例子。也是最简单最easy的一个例子。 这里对接的grpc服务与你自己的业务代码结合的通道接口。与MVC 中 C 是一个位置, 它属于业务应用类代码。

server

grpc的服务端,使用easy.rpc 只需要简短的代码就可以构筑,rpc应用服务端。

  • run

运行前先修改下etcd 的地址;集群多个etcd地址用分号隔开即可。为了运行命令简便,这里并没有使用flag等。

先跳转到 cd examples/rpc/server

运行 go build && ./server

  • 服务端配置ETCD
    // 配置ETCD服务
    eoption := &etcd.Option{}
    eoption.Conv(etcdAddr)
    etcd.NewWithOption(eoption)
	
  • 服务端配置grpc

业务接口注册需要在Serv()监听之前去注册。

    // New 一个rpc 监听服务
    server := cgrpc.NewServer(&cgrpc.Config{
        Name:      "server1",
        Addr:      serverAddr,
        Namespace: namespace,
    })
    
    // 绑定业务接口到 rpc服务
    // 可以被多次使用RegisterService,我们用的append
    server.RegisterService(
        func(server *grpc.Server) {
            helloworld.RegisterGreeterServer(server, &hello{})
        },
    )
    
    // 监听;如果您有主监听接口,那么可以用go 并发运行
    server.Serv()
  • 业务接口
// server is used to implement helloworld.GreeterServer.
type hello struct {
    helloworld.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *hello) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
    log.Info("Received: %v", in.GetName())
    return &helloworld.HelloReply{Message: "Hello " + in.GetName()}, nil
}
client

grpc的客户端;load balance 是在客户端实现的.

  • run

这里与server 是一样的,修改下etcd 地址即可

跳转到项目目录: cd examples/rpc/client

运行: go build && ./client

  • 变量
var (
	etcdAddr  string = "127.0.0.1:12379"
	namespace        = "easy"
)
  • ETCD 初始化

与服务端一样的

    // plan 1
    //eoption := &etcd.Option{}
    //eoption.Conv(etcdAddr)
    //etcd.NewWithOption(eoption)
	
    // plan2
    etcd.NewWithOption(option.OptionWith(nil).Default(
        option.OptionFunc(func() (string, any) {
        return "Endpoints", strings.Split(etcdAddr, ";")
        })),
    )
  • grpc 客户端配置

代码中client对象是需要全局暴漏(public)。handle调用部分可以写在任意地方,是与原生grpc调用一样的,只要在ClientConn的有效生命周期内通信调用即可。

使用匿名函数封装可以避免暴漏全局变量,但为了兼容grpc使用习惯,就没有去封装。

    client := cgrpc.NewClient(option.OptionWith(&struct {
        Name      string
        Namespace string
    }{"server1", namespace}))
	
    client.Start()
    
    // do your things
    handle(client.ClientConn)
    // just for test
    client.Wait()
    
    // close
    client.Close()
  • handle 业务处理

handle 写这十几行,其实为了压力测试,持续性测试等。

func handle(clientConn grpc.ClientConnInterface) {
    c := helloworld.NewGreeterClient(clientConn)
    ticker := time.NewTicker(2 * time.Second)
    i := 1
    for range ticker.C {
    
        resp1, err := c.SayHello(
            context.Background(),
            &helloworld.HelloRequest{Name: fmt.Sprintf("xiaoming-%d", i)},
        )
        if err != nil {
            log.Fatal("SayHello call error:%v", err)
            continue
        }
        log.Info("SayHello Response:%s\n", resp1.Message)
    
        i++
    }

}

仅仅是这2句是用的grpc,也是核心调用,其他的是多余的

    c := helloworld.NewGreeterClient(clientConn)
    resp1, err := c.SayHello(
        context.Background(),
        &helloworld.HelloRequest{Name: fmt.Sprintf("xiaoming-%d", i)},
    )

Directories

Path Synopsis
rpc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL