Search

Search IconIcon to open search

太吾绘卷Mod RPC前后端通信 readme

Last updated Jun 15, 2023

1
E:\SteamLibrary\steamapps\workshop\content\838350\2879349207

# TWPRC

太吾RPC框架(其实应该叫IPC, 进程间调用( ╯□╰ ))

# 功能介绍

可以以同步方式调用后端的函数, 就好像在调用本地函数

# 特性介绍

  1. 易用 接口简单 如: int result3 = (int)client.CallMethod(ClassTpyeName, "TestMethod", new List<int> { 4, 5, 6 });
  2. 同步调用, 方便debug
  3. 高性能, 通信消耗几乎没有, 不额外占用系统资源
  4. 解决目前mod加载依赖问题, 不需要框架优先加载(好吧不需要了)
  5. 支持多线程(应该)

# 使用方法

前端的依赖项添加TWRPC.dll, 在合适的实际调用TWRPCClient.CreateStream (strname)方法, 随后就可以通过该实例调用远端函数

详情可以看示例mod
(其实调用远端方法并不需要name,加入该值是为了方便debug,但现在没有相关函数)

# 技术白皮书

  1. 通信方式
    使用基于内存映射的无锁RingBuffer结构进行通信, 性能大概为1GB/s, 来回时延0.005ms/次. 性能大概是socket的100倍, 管道的10倍. 通信几乎只消耗两三个系统调用, 这也是使用同步调用的底气.

  2. 无额外性能消耗, 不额外占系统资源
    采用单连接多路复用的方式,前后端各有一个读线程和写线程, 皆使用阻塞读写设计, 在无通信的时候不占用系统资源.

  3. 依赖问题解决(好了现在不用了)
    使用基类对外提供方法, 使用反射创建实现类, 通过虚函数提供服务

  4. 序列化
    使用Protobuf-net进行序列化, 可以方便添加自定义的序列化类, 同时也支持游戏内数据类型的序列化(未测试)

  5. 前后端通信过程

    1. 首先, 在调用函数的时候, 会收集一个方法所需要的所有参数, 包括方法所属的类信息, 方法名, 参数类型信息, 参数信息.
    2. 将收集到的这些信息序列化成二进制流, 发送到后端, 后代将二进制流反序列化这些参数, 调用方法, 返回返回值
  6. Type是如何匹配的

    前端的Type和后端的Type分属不同的Assembly, 他们是怎么匹配上的呢? Type由三个参数唯一指定, NameSpace, TypeName, AssemblyName。

    在得到这个唯一标识符后,框架会使用Type.GetType(typename)方法来获取类型。

    对于系统类型, 只需要NameSpace和TypeName即可. 前后端即是根据这个参数来匹配类型。

    在需要传递自定义数据类型数据时,推荐的做法是将自定义类型放到一个单独的Assembly中,前后端分别引用这个Assembly,这样无需额外处理就能识别到这类型。

    对于游戏内部使用的类型,他们分属不同的Assembly,本来匹配是会失败的,框架对此做了额外的处理,匹配失败时,会到其特定的Assembly中查找型。 因而能够匹配上。


  1. 目前Windows only 主要是因为.net 没有提供好用的进程间同步api, 而底层的RingBuffer又需要同步机制。恰巧我又很少用Linux、mac,所以就先咕咕了。

# Todo

  1. 目前仅支持静态方法,因为还没想好怎么实例化类。目前想法是提供调用全局对象的实例方法接口
  2. 提供一些消息通知机制和注册接口以简化类名
  3. 支持泛型方法