UE4.27, 揣摩源码, 网络同步 (三) RPC

6.  RPC

  6.1.  RPC是网络同步的一部分,全称Remote Procedure Call。属性同步只能从服务端向客户端单向传递信息,而RPC可以双向传递消息
  6.2.  类型

    6.2.1.  Server调用,Actor所属的Client执行
    6.2.2.  Client调用,Server执行
    6.2.3.  Server调用,Server和所有Client执行

    6.2.4.  定义示例

       UFUNCTION(Client)

        void ClientRPCFunction();

       UFUNCTION(Server)

        void ServerRPCFunction();

       UFUNCTION(NetMulticast)

        void MulticastRPCFunction();

  6.3.  调用堆栈

    UObject::ProcessEvent

      AActor::GetFunctionCallspace

       检查函数调用域是否为remote,有趣的是,它返回值按值取与来进行判断,这是因为该函数内部返回的情形并不是单纯的某枚举值,存在返回枚举值A | 枚举值B的状况。

       我个人认为既然允许位运算参与逻辑判断,枚举的定义应该是形如0b的,但是UE却是0x定义的,对此表示疑惑

       这个枚举定义形式是相当典型的,命名空间内定义Type的实际枚举,配合一个内联函数返回宽字符头来方便转化枚举值为字符串。这显然是调试考量

        AActor::CallRemoteFunction

          UNetDriver::ProcessRemoteFunction

            // 寻找连接,如果需要,则遍历连接

              // 如果是多播

              InternalProcessRemoteFunctionPrivate

              // 如果不是多播

              InternalProcessRemoteFunction 调用 InternalProcessRemoteFunctionPrivate

              我们可以观察到,如果不是多播,进行rpc的条件是该actor得有连接NetConnection 这就是我们配置actor需要考察owner的原因之一

              没有owner,或者说owner链条不到PlayerController,就找不到connection,这一步是过不了的

 

              进一步的,我们可以观察到这俩函数的区别:形参接受的参数connection不同,这个自然,多播需要分别遍历connection,

              还有就是parameter的处理区别,在多播的时候会构造一个共享的序列化,其内部是由 FLayout成员中bool变量维护的 只执行一次的函数体

                 InternalProcessRemoteFunctionPrivate

                检查channel是否创建,没创建就创建一个

                (居然还有第一人称actor的注释,哈哈哈哈哈)

 

                  ProcessRemoteFunctionForChannelPrivate

                    SendPropertiesForRPC

                      底层send

posted @ 2025-01-10 23:59  在找饭吃的陈  阅读(96)  评论(0)    收藏  举报