凯发娱发k8

et框架6.0分析三、网络通信 -凯发娱发k8

2023-10-20

et框架的消息机制贯彻始终,包含entity消息(awake,update ...),自定义(customer)消息,网络消息等。而et系统的进程包含了客户端、gate等各种类型的服务器,进程包含各种服务器客户端之间通过网络消息进行通信进行工作。

结构图为了更加明确整体关系,进行了一定程度的简化,剔除掉了一些消息解包等一些细节

netcompontent网络组件有client客户端、server服务器(gate)、inner内网服务等多态,进程业务使用网络组件进行通信,网络组件会对连接建立一个secsiom会话对象,封装连接信息和相关操作

service和channel实现负责netcompontent和session的功能,有tcp长连接、web网页、kcp无连接可靠协议的多态(若不熟悉kcp协议,可以参考之前写的文章 跳转链接: kcp协议浅析)。

channel对应一个session连接,封装了对底层tcp等协议库的操作。
service对应一个netcompent组件,对应netcompent管理多个session,server管理和调度一堆channel的工作。

netservices负责调度多个service对象的在网络线程和主线程工作任务,et开了网络线程处理网络相关,某些进程需要多个网络组件(比如gate服务器同时需要server、inner网络组件,接收转发客户端消息)。

netcomponentonreadevent是不同类型网络组件的消息处理器。

netclientcomponentonreadevent对应客户端client,处理普通消息和rpc调用。
netinnercomponentonreadevent对应服务器内网类型inner,处理actor消息
netservercomponentonreadevent对应服务外网,处理actor消息、rpc调用、普通消息

以典型的tcp协议类型为例,其他实现类似,看图相信都能理解,不多赘述。有一些要注意的点:

如上述,et开了一个线程处理网络相关,一些工作使用了“生产-消费”task任务这种方式。
使用了异步socket

tcp发消息

tcp收消息

et框架在基础网络消息通信基础使用了actor模型、prc等相关技术思想(某些思想和实现有调整)进行了拓展,提供多个进程的互相调用机制。

先对相关技术做一个简介:

actor模型

在计算机科学中,actor模型(actor model)是一种并发运算上的模型。“actor”是一种程序上的抽象概念,被视为并发运算的基本单元:当一个actor接收到一则消息,它可以做出一些决策、创建更多的actor、发送更多的消息、决定要如何回答接下来的消息。actor可以修改它们自己的私有状态,但是只能通过消息间接的相互影响(避免了基于锁的同步)

这是维基百科中对于actor模型的描述,简单理解它就是提供了一种消息机制避免了基于锁的同步。一些经典的应用场景是多线程,在et框架中它的应用场景是多进程,类似的它提供了一种机制:直接通过id发消息,不用关心实例在哪个进程。

rpc

分布式计算中,远程过程调用(英语:remote procedure call,rpc)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一个地址空间(通常为一个开放网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额外地为这个交互作用编程(无需关注细节)。rpc是一种服务器-客户端(client/server)模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统

rpc机制通过一些手段抹平了不同进程的差异,使得进程间的调用可以和本地异步调用一样处理。

了解了这两种技术,下面来看et框架对其的应用和如何实现多进程调用的。

消息协议类型

如上图所示消息类型分为三种:

message 消息,无需应答
request 请求,对应一个response应答
response 应答,对应一个请求

注意request和response一定成对定义,且其message一定包含一个rpcid字段

消息类型可以被前缀修饰,修饰有三种:

none 客户端与服务器(gate)之间不需要转发的消息。(注意这里不是修饰字符不是"none",而是""表示没有)
actor 服务器内网之间的消息
actorlocation 客户端与服务器需要转发的消息。

修饰字符可以修饰任意消息类型,组合起来一共有9种消息。

如这个登录到gate的协议:

//responsetype g2c_logingate
message c2g_logingate // irequest
{
int32 rpcid = 1;
int64 key = 2; // 帐号
int64 gateid = 3;
} message g2c_logingate // iresponse
{
int32 rpcid = 1;
int32 error = 2;
string message = 3;
int64 playerid = 4;
}

c2g_logingate 在消息名后面注明了消息类型,并在消息名上面注明了应答包的消息类型,并且包含一个rpcid的字段,这些都必须的,表示这是个不需要转发的、需要应答的请求消息。而消息名前缀只是方便理解,起到注释的作用:表示这是client进程发送给gate服务器进程的消息。
g2c_logingate 同上,是上述c2g_logingate请求的应答消息。

rpc调用过程

如图所示,进行rpc调用时,生成一个新的rpcid并带入请求包中,同时把调用信息存起来。对方应答时,会把请求包的rpcid传入到应答包中。在收到消息时如果是resp类型消息会调用onresp方法,通过应答包的rpcid取出rpcinfo,通过rpcinfo取消调用rpccall函数的异步阻塞。

public static void onresponse(this session self, iresponse response)
{
if (!self.requestcallbacks.trygetvalue(response.rpcid, out var action))
{
return;
} self.requestcallbacks.remove(response.rpcid);
if (errorcore.isrpcneedthrowexception(response.error))
{
action.tcs.setexception(new exception($"rpc error, request: {action.request} response: {response}"));
return;
}
action.tcs.setresult(response);
}

action.tcs.setresult会取消异步的阻塞,执行await后面的语句,详情见之前写的文章 跳转链接: c#异步编程

actor模型实现

在et框架的设计中,actor其实是一个带有mailboxcomponent的组件。其具体的实现方式,et有比较详细的文档说明,有实现思路和使用方式的介绍,这里贴出来,不做赘述。

跳转链接: et actor模型 官方介绍

跳转链接: actor模型介绍
跳转链接: rpc介绍

et框架6.0分析三、网络通信的相关教程结束。

网站地图