金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
grpc-go与actor模式

(金庆的专栏 2018.6)

grpc-go服务器的每个请求都在一个独立的协程中执行。
网游服务器中,一般请求会调用游戏房间的方法,而房间是一个独立的协程。
可以将房间实现为actor,grpc请求通过Call()或Post()方法来执行。
其中Call()会等待返回,而Post()会异步执行无返回值。

type Room struct {
    // actC 是其他协程向Room协程发送动作的Channel,协程中将依次执行动作。
    // Action 动作, 是无参数无返回值的函数.
    actC chan func()

    ...
}

// Run 运行房间协程.
func (r *Room) Run() {
    ticker := time.NewTicker(20 * time.Millisecond)
    defer ticker.Stop()

    for r.running {
        select {
        case act := <-r.actC:
            act()
        case <-ticker.C:
            r.tick()
        }
    }
}

// Call calls a function f and returns the result.
// f runs in the Room's goroutine.
func (r *Room) Call(f func() interface{}) interface{} {
    // 结果从ch返回
    ch := make(chan interface{}, 1)
    r.actC <- func() {
        ch <- f()
    }
    // 等待直到返回结果
    return <-ch
}

// Post 将一个动作投递到内部协程中执行.
func (r *Room) Post(f func()) {
    r.actC <- f
}

grpc服务方法如:

func (m *RoomService) Test(ctx context.Context, req *pb.TestReq) (*pb.TestResp, error) {
    conn := conn_mgr.GetConn(ctx)
    if conn == nil {
        return nil, fmt.Errorf("can not find connection")
    }

    room := conn.GetRoom()
    resp := room.Call(func() interface{} {
        return room.Test(req)
    })

    return resp.(*pb.TestResp), nil
}
posted on 2018-06-12 11:15 金庆 阅读(810) 评论(0)  编辑 收藏 引用 所属分类: 9. 其它3. Golang

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理