Apache Thrift客户端c#中的运行时问题

时间:2013-07-24 20:00:04

标签: c#-4.0 thread-safety rpc thrift thrift-protocol

我正在研究用C#编写的客户端 - 服务器应用程序,它是使用Apache THRIFT RPC框架构建的。

我们已经创建了几个带有服务定义的IDL文件(.thrift文件)。这些服务已在服务器中实现,并从客户端调用。

下面给出了IDL文件中结构和服务定义的示例

struct ViewColumn {

1: string ColumnProperty,
2: i32 ColWidth,
3: i32 ColPosition,
4: bool ColAscending,
5: i32 ColSortOrder,

}

struct FormView {

   1: i32 ID
   2: string formname
   3: list<ViewColumn> SelectedColumns

}

服务FormQueries {

   1: FormView FetchFormView()

}

整个应用程序中定义了许多此类服务。

在服务器中,服务已实现如下

    Public FormView FetchFormView() {

  return something

}

客户端和服务器的配置如下

客户端 1. TSocket 2 TBinaryprotocol 3. TMultiplexedProtocol

服务器 1. TserverSocket 2.多路复用处理器 3. TbinaryProtocol

从客户端调用服务如下

var f = Queries.FetchFormView()

我们遇到了一些问题。

  1. FetchFormView()返回null
  2. 的System.OutOfMemoryException
  3. 下面提供了这些错误的堆栈跟踪

    Exception of type 'System.OutOfMemoryException' was thrown.
       at Thrift.Protocol.TBinaryProtocol.ReadStringBody(Int32 size) 
       at Thrift.Protocol.TBinaryProtocol.ReadMessageBegin() 
       at Thrift.Protocol.TProtocolDecorator.ReadMessageBegin() 
       at Queries.recv_FetchFormView()
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    
    FetchFormView failed: unknown result (result is null)
    NOTE: This error occurs with other defined services also
       at Queries.recv_FetchFormView()
       at Queries.Client.FetchFormView()
       at Queries.FetchFormView()
       at System.Windows.Forms.ToolStripDropDownItem.OnDropDownShow(EventArgs e)
       at System.Windows.Forms.ToolStripMenuItem.OnDropDownShow(EventArgs e)
       at System.Windows.Forms.ToolStripDropDownItem.ShowDropDownInternal()
       at System.Windows.Forms.ToolStripDropDownItem.ShowDropDown(Boolean mousePush)
       at System.Windows.Forms.ToolStripMenuItem.OnMouseButtonStateChange(MouseEventArgs e, Boolean isMouseDown)
       at System.Windows.Forms.ToolStripMenuItem.OnMouseDown(MouseEventArgs e)
       at System.Windows.Forms.ToolStripItem.HandleMouseDown(MouseEventArgs e)
       at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
       at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
       at System.Windows.Forms.ToolStrip.OnMouseDown(MouseEventArgs mea)
       at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ToolStrip.WndProc(Message& m)
       at System.Windows.Forms.MenuStrip.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    

    如果您有在企业级应用程序中使用Apache THRIFT的经验,请向我提供见解/解决方案/想法和最佳方法。

    这是一个严峻的形势。任何帮助表示赞赏。

    提前感谢

    罗米

    更新 - 2013年3月26日

    我已经即兴创作了一个解决方案。我正在关闭/处理并在每次服务调用之前重新创建传输和协议对象。这是与服务器连接的低效方式,但它正在工作。我正在考虑使每个服务调用异步。可能这将是一个更好的解决方案。

1 个答案:

答案 0 :(得分:1)

如果您在服务器上使用TMultiplexedProcessor,则必须在客户端上使用TMultiplexedProtocol。

以下是您报告的堆栈:

  • 客户端1. TSocket&amp; TBinaryprotocol
  • 服务器1.TserverSocket 2.多路复用处理器3。 TbinaryProtocol

它应该是这样的:

  • 客户端1. TSocket 2. TBinaryprotocol 3.TMultiplexedProtocol
  • 服务器1. TServerSocket 2. TMultiplexedProcessor 3. TBinaryProtocol

在客户端上是这样的:

TTransport trans = new TSocket("localhost", 9090));
TProtocol proto = new TBinaryProtocol(trans);
TMultiplexedProtocol mproto = new TMultiplexedProtocol(proto, "FormQueries");
FormQueries.Client Queries = new FormQueries.Client(mproto);
var f = Queries.FetchFormView()

这假定FormQueries服务已使用“FormQueries”键添加到服务器上的TMultiplexedProcessor,此字符串是服务器确定要调用哪个服务的方式,因此它必须在客户端和服务器上匹配。