从 C# 到 C++/CLI 进行 RPC 调用时超时

Posted

技术标签:

【中文标题】从 C# 到 C++/CLI 进行 RPC 调用时超时【英文标题】:timeout while making RPC Call form C# to C++/CLI 【发布时间】:2014-07-24 07:28:12 【问题描述】:
public ref class RequestMessage

public:
    [ProtoMember(1)]
    Int32 Number1;
    [ProtoMember(2)]
    Int32 Number2;
;

// Response message declared as managed class.
public ref class ResponseMessage

    public:
    [ProtoMember(1)]
    Int32 Result;
;

void OnMessageReceived(System::Object ^sender, TypedRequestReceivedEventArgs<RequestMessage^> ^e);
int main(array<System::String ^> ^args)

    ISerializer ^aSerializer = gcnew ProtoBufSerializer();
    IDuplexTypedMessagesFactory ^aReceiverFactory = gcnew DuplexTypedMessagesFactory(aSerializer);
    IDuplexTypedMessageReceiver<ResponseMessage^, RequestMessage^> ^aReceiver =aReceiverFactory->CreateDuplexTypedMessageReceiver<ResponseMessage^, RequestMessage^>();
    aReceiver->MessageReceived +=    gcnew System::EventHandler<Eneter::Messaging::EndPoints::TypedMessages::TypedRequestReceivedEventArgs<RequestMessage ^> ^>(&OnMessageReceived);
    IMessagingSystemFactory ^aMessaging = gcnew TcpMessagingSystemFactory();
    IDuplexInputChannel ^anInputChannel =aMessaging->CreateDuplexInputChannel("tcp://127.0.0.1:4502/");
    aReceiver->AttachDuplexInputChannel(anInputChannel);
    Console::WriteLine("The calculator service is running. Press ENTER to stop.");
    Console::ReadLine();
    aReceiver->DetachDuplexInputChannel();

    return 0;


void OnMessageReceived(System::Object ^sender,TypedRequestReceivedEventArgs<RequestMessage ^> ^e)

    ResponseMessage ^aResponseMessage = gcnew ResponseMessage();
    aResponseMessage->Result = e->RequestMessage->Number1 + e->RequestMessage->Number2;

    Console::WriteLine("0 + 1 = 2", e->RequestMessage->Number1, e->RequestMessage->Number2, aResponseMessage->Result);

    // Send back the response message.
    IDuplexTypedMessageReceiver<ResponseMessage^, RequestMessage^> ^aReceiver = (IDuplexTypedMessageReceiver<ResponseMessage^, RequestMessage^>^)sender;
    aReceiver->SendResponseMessage(e->ResponseReceiverId, aResponseMessage);


上面的代码是使用协议缓冲区的 RPC 的服务器代码,但是除了客户端之外,每个客户端都无法从服务器获得任何响应,相同的代码在 C# 中工作,但它不适用于 C++...我认为我们可以编写一个代码等同于 C++/CLI 中的 C# 代码。但此代码无法正常工作,我的客户端可以正常使用 C# 代码。 我注意到没有调用 OnMessageRecived() 函数。

这是本机 C++ 和 C# 服务器代码的示例,但我想使用纯托管 C++ http://eneter.blogspot.in/2013/12/native-c-how-to-communicate-with-net.html

任何人都可以告诉我发生了什么事...我该如何解决这个问题。

【问题讨论】:

这是一个环境问题。当您遇到与 RPC 相关的错误时,您应该将反恶意软件或防火墙视为麻烦制造者。他们会阻止通信尝试,这会产生超时。 不,没有那样的东西。在 C# 中编译的相同程序正在运行......但使用 C++/CLI 的相同代码不起作用......而且我没有使用任何防火墙和反恶意软件... 【参考方案1】:

我不是 100% 确定,但我认为您的问题可能是 RequestMessage 和 ResponseMessage 声明中缺少属性 [ProtoContract]。

例如在服务方面:

[原合同] 公共参考类 RequestMessage 上市: [原型成员(1)] Int32 编号1; [原型成员(2)] Int32 编号 2; ;

然后在客户端:

[原合同] 公共类请求消息 [原型成员(1)] 公共 int Number1 得到;放; [原型成员(2)] 公共 int Number2 得到;放;

【讨论】:

以上是关于从 C# 到 C++/CLI 进行 RPC 调用时超时的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 C++-CLI 回调和委托将字符串从 C++-CLI 传递到 C#

从 C++/CLI 调用 C# dll 函数

C++ 到 C# 事件处理

使用 C++/CLI 包装器将二维数组从 C# 传递到非托管 C++

为啥 C++/CLI 编译器不为过时的属性调用生成警告?

Thrift RPC 从 c# 中的 thrift 客户端失败到在 HBase 服务器上旋转的 thrift 服务器