五邑隐侠,本名关健昌,12年游戏生涯。 本教程以Go语言为例。
 
P2P网络为服务进程间、服务进程与客户端间通信提供了便利,在这个基础上可以搭建服务。
在服务层,通信包可以通过定义协议号来确定该包怎样处理。每个协议号对应一个Processor,Processor定义为一个interface
type Processor interface {
    OnHandleRequest(req *Request, resp *Response) (int32, error)
}

协议号又可以拆分为模块号和命令号。一个模块对应一个Service,该模块下每个命令对应一个Processor,通过map结构做映射

type Service struct {
    mapCmd2Processor map[uint16]Processor
}
Service提供方法添加、删除、获取Processor
func AddProcessor(cmd uint16, p Processor) error
func GetProcessor(cmd uint16) Processor
func RemoveProcessor(cmd uint16) error
提供个入口方法,把该模块的Service的请求分发到对应的Processor
func (s *Service) OnHandleRequest(req *Request, resp *Response) (int32, error) {
p, ok := s.mapCmd2Processor[req.Cmd]
    if ok {
        return p.OnHandleRequest(req, resp)
    }
}
服务 Server 是 Service 的集合,通过模块号进行映射
type Server struct {
    mapMod2Service map[uint16]*Service
    rpc            *Rpc
}
同样提供方法添加、删除、获取Service
func AddService(mod uint16, srv *Service) error
func GetService(mod uint16) *Service
func RemoveService(mod uint16) error
这样当收到一个请求包,对协议号拆分为模块号和命令号,通过模块号获取到对应的Service,调用Service的 OnHandleRequest 进行处理
serv := s.GetService(req.Mod)
if serv != nil {
code, err := serv.OnHandleRequest(req, resp)
}
Server 基于 P2P 层,P2P的包是通用的格式,不同的游戏服务端进程,都有可能有不同的包格式,例如,客户端包格式和服务内部通信的包格式是有差别的。为了让服务通用,引入服务适配器,在请求和响应时做预处理,转化为通用的 Request 和 Response
type ServerAdapter interface {
    OnRequest(payload []byte) (*Request, error)
    OnResponse(pack *Response) ([]byte, error)
} type Server struct {
    mapMod2Service map[uint16]*Service
    rpc            *Rpc adapter        ServerAdapter
}
这样在服务层都是基于 Request 和 Response进行处理,由具体业务对业务包做转换
type Request struct {
    Mod      uint16
    Cmd      uint16
    Payload  []byte
} type Response struct {
    Mod      uint16
    Cmd      uint16
    Payload  []byte
}
服务 Server 还可以提供拦截器,拦截器的好处是对一些阶段进行统一处理,而且可以通过插入新拦截器进行扩展,随时都可以替换这个阶段的逻辑(例如从 json 包变成 proto 包、增加二进制头等),拦截器可以针对3个阶段: 请求处理前,请求处理后,响应发送后
type Interceptor interface {
    OnPreHandle(req *Request, resp *Response) (int32, error)
    OnHandleCompletion(req *Request, resp *Response) (int32, error)
    OnResponseCompletion(req *Request, resp *Response) error
}
除了全局拦截器,还可以添加针对某个模块 Service 的拦截器,对某个 Service 做特殊拦截处理
type InterceptorList []Interceptor

type Server struct {
    mapMod2Service map[uint16]*Service
    rpc            *Rpc adapter        ServerAdapter
globalInterceptors InterceptorList
mapMod2Interceptors map[uint16]InterceptorList
}
这样一个请求的处理过程就变成
// adapter
req, err := s.adapter.OnRequest(payload)
resp := NewResponse(req)
// prehandle
interList, ok := s.mapMod2Interceptors[req.Mod]
s.prehandle(interList, ok, req, resp)
// handle
serv := s.GetService(req.Mod)
code, err := serv.OnHandleRequest(req, resp)
// handle complete
s.handleCompletion(interList, ok, req, resp)
s.push(resp)
// response complete
s.responseCompletion(interList, ok, req, resp)
服务机制介绍到这里,接下来聊聊 RPC 机制

go语言游戏服务端开发(三)——服务机制的更多相关文章

  1. Swift3.0服务端开发(三) Mustache页面模板与日志记录

    本篇博客主要介绍如果在Perfect工程中引入和使用Mustache页面模板与日志记录系统.Mustache页面模板类似于PHP中的smarty模板引擎或者Java中的JSTL标签.当然Mustach ...

  2. kafka客户端和服务端开发(三)

    前面我们已经搭建了kafka的单机和集群环境,分别写了简单的实例代码,对于代码里面使用到的参数并没有做解释.下面我们来详细说一下各个参数的作用. 1. 创建kafka生产者 kafka生产者有3个必选 ...

  3. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

  4. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  5. 微服务项目开发学成在线_day01_CMS服务端开发

    05-CMS需求分析-什么是CMS 什么是CMS?CMS (Content Management System)即内容管理系统,不同的项目对CMS的定位不同.CMS有哪些类型? 每个公司对每个项目的C ...

  6. Day01_搭建环境&CMS服务端开发

    学成在线 第1天 讲义-项目概述 CMS接口开发 1 项目的功能构架 1.1 项目背景 受互联网+概念的催化,当今中国在线教育市场的发展可谓是百花齐放.如火如荼. 按照市场领域细分为:学前教育.K12 ...

  7. Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)

    前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架.本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在<Swift3.0服务端开发(一)>这篇 ...

  8. 如何有效快速提高Java服务端开发人员的技术水平?

    我相信很多工作了3-5年的开发人员都会经常问自己几个问题: 1.为什么总是感觉技术没有质的提高? 2.如何能够有效和快速的提高自身的技术水平? 3.如何进入到一个牛逼的大公司,认识牛逼的人? 这篇文章 ...

  9. 从架构师视角看是否该用Kotlin做服务端开发?

    前言 自从Oracle收购Sun之后,对Java收费或加强控制的尝试从未间断,谷歌与Oracle围绕Java API的官司也跌宕起伏.虽然Oracle只是针对Oracle JDK8的升级收费,并释放了 ...

  10. RTSP服务端开发概述

    一 概述 RTSP(Real Time Streaming Protocol),RFC2326,实时音视频流传输协议,是TCP/IP协议体系中的一个应用层协议.该协议定义了一对多应用程序如何有效地通过 ...

随机推荐

  1. Windows安装Hyper-V并优化部署Linux虚拟机

    安装Hyper-V 打开服务器管理器-->添加角色和功能-->下一步,选择Hyper-V,如图所示 然后一直默认往下走,一直到安装完成,然后重新启动计算机,如图所示 其中涉及的虚拟交换机. ...

  2. TCP文件上传实现

    TCP文件上传实现 服务端: package net.study; import java.io.*; import java.net.ServerSocket; import java.net.So ...

  3. 成为编程大牛很简单,把这些书看个八成就OK

    原文链接:http://lucida.me/blog/developer-reading-list/ 本文把程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍 ...

  4. 快速上手CH340N电路设计(CH340N USB转串口模块 USB Type-C接口 CH340系列芯片讲解)

    一.上模块          二.功能分析 l  芯片:CH340N l  输入接口:USB.TYPE-C l  输出接口:TTL(5V\3.3V\GND\TX\RX) l  指示灯:电源.TX.RX ...

  5. sqli-labs lesson5-6 布尔盲注 报错注入 延时注入

    LESSON 5: 典型的布尔盲注. 盲注:sql注入过程中,sql语句的执行结果不回显到前端,这个时候就只能用一些别的方法进行判断或者尝试,这个判断或者尝试就叫做盲注.盲注又分为:1.基于布尔SQL ...

  6. Layui-自定义函数及调用

    控件 表格 时间范围 页面展示 场景 页面中选择开始时间和结束时间表格变化 使用 html代码 <div> <form class="layui-form" ac ...

  7. STM32—4线SPI驱动SSD1306 OLED

    文章目录 一.OLED简介 二.驱动SSD1306所需知识 1.引脚介绍 2.通信时序 3.显存GRAM 4.字库 5.SSD1306基本命令 三.代码讲解 1.相关引脚配置 2.模拟SPI通信 3. ...

  8. 谈谈 Nginx 那点事【一】

    为什么突然决定总结Nginx ? 不知不觉8月份又要过完了,时间真是个无情的崽种. 写Nginx 首先,主要源于最近项目部署工作中和公司技术中心的人对接部署相关事宜流程太繁琐了.每个部门有各自的工作安 ...

  9. Python小白的数学建模课-19.网络流优化问题

    流在生活中十分常见,例如交通系统中的人流.车流.物流,供水管网中的水流,金融系统中的现金流,网络中的信息流.网络流优化问题是基本的网络优化问题,应用非常广泛. 网络流优化问题最重要的指标是边的成本和容 ...

  10. npm 基本命令的使用

    1.npm -v 查看npm版本 2.使用npm命令安装模块 npm install Module Name 例如安装jquery模块 npm install jquery 3.卸载模块 npm un ...