Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何同时使用多个TSocketTransport? 我正在研究一个C服务,它通过WebAPI接收数据,将它们转换并将它们推到一个C++底层代理上。 C++部分是服务器,C是客户端。 该接口是从C++部分定义的。从该接口生成一个C#库,其中 .\thrift-0.13.0.exe--gen netstd.\agent.thrift_C#_.net Core_Thrift - Fatal编程技术网

如何同时使用多个TSocketTransport? 我正在研究一个C服务,它通过WebAPI接收数据,将它们转换并将它们推到一个C++底层代理上。 C++部分是服务器,C是客户端。 该接口是从C++部分定义的。从该接口生成一个C#库,其中 .\thrift-0.13.0.exe--gen netstd.\agent.thrift

如何同时使用多个TSocketTransport? 我正在研究一个C服务,它通过WebAPI接收数据,将它们转换并将它们推到一个C++底层代理上。 C++部分是服务器,C是客户端。 该接口是从C++部分定义的。从该接口生成一个C#库,其中 .\thrift-0.13.0.exe--gen netstd.\agent.thrift,c#,.net-core,thrift,C#,.net Core,Thrift,生成的类之一是AgentPush.Client,它通过Thrift管理传输,并包含openTransportAsync和pushEventAsync方法 /// generated code public async Task<PushEventResult> pushEventAsync(PushEventData data, CancellationToken cancellationToken = default(CancellationToken)) {

生成的类之一是AgentPush.Client,它通过Thrift管理传输,并包含openTransportAsync和pushEventAsync方法

  /// generated code
  public async Task<PushEventResult> pushEventAsync(PushEventData data, CancellationToken cancellationToken = default(CancellationToken))
  {
     await OutputProtocol.WriteMessageBeginAsync(new TMessage("pushEvent", TMessageType.Call, SeqId), cancellationToken);        
     var args = new pushEventArgs();
     args.Data = data;        
     await args.WriteAsync(OutputProtocol, cancellationToken);
     await OutputProtocol.WriteMessageEndAsync(cancellationToken);
     await OutputProtocol.Transport.FlushAsync(cancellationToken);        
     var msg = await InputProtocol.ReadMessageBeginAsync(cancellationToken);
     if (msg.Type == TMessageType.Exception)
     {
        var x = await TApplicationException.ReadAsync(InputProtocol, cancellationToken);
        await InputProtocol.ReadMessageEndAsync(cancellationToken);
        throw x;
     }
     var result = new pushEventResult();
     await result.ReadAsync(InputProtocol, cancellationToken);
     await InputProtocol.ReadMessageEndAsync(cancellationToken);
     if (result.__isset.success)
     {
        return result.Success;
     }
     throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "pushEvent failed: unknown result");
  }
我从另一个类中使用它来封装PushEventData:

private static SemaphoreSlim _lockGuard = new SemaphoreSlim(semaphoreThreads, semaphoreThreads);

if (await _lockGuard.WaitAsync(_millisecondsThriftTimeout, ct))
{
    try 
    { 
       var agentPushClient = _agentPushClientFactory.GetNextAvailablePushClient();  // get the next client with dedidacted TTransport in a rolling pool of 5.
       var result = await agentPushClient.PushEventAsync(data, ct);  
    } 
    finally 
    {
      _lockGuard.Release();
    }
}
semaphoreThreads==1确保与thrift的单一连接。所有的工作都很顺利

现在,我需要同时拥有多个连接,所以我把信号量线程从C++代理的节省服务器(这里5)允许的线程中提升,并期望每个连接都转到服务器端的另一个线程。 但是,我得到System.Net.Sockets.SocketException

System.Threading.Tasks.TaskCanceledException: The operation was canceled.
 ---> System.IO.IOException: Unable to read data from the transport connection: Operation canceled.
 ---> System.Net.Sockets.SocketException (125): Operation canceled
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   
System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowOperationCanceledException()
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
   at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location where exception was thrown ---
   at Thrift.Transport.Client.TStreamTransport.ReadAsync(Byte[] buffer, Int32 offset, Int32 length, CancellationToken cancellationToken)
   at Thrift.Transport.TTransport.ReadAllAsync(Byte[] buffer, Int32 offset, Int32 length, CancellationToken cancellationToken)
   at Thrift.Protocol.TBinaryProtocol.ReadI32Async(CancellationToken cancellationToken)
   at Thrift.Protocol.TBinaryProtocol.ReadMessageBeginAsync(CancellationToken cancellationToken)
   at AgentPush.Client.pushEventAsync(PushData data, CancellationToken cancellationToken)
   
System.Threading.Tasks.TaskCanceledException:操作已取消。
--->System.IO.IOException:无法从传输连接读取数据:操作已取消。
--->System.Net.Sockets.SocketException(125):操作已取消
---内部异常堆栈跟踪的结束---
位于System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThroweException(SocketError错误,CancellationToken CancellationToken)
System.OperationCanceledException:操作已取消。
在System.Threading.CancellationToken.ThrowoOperationCanceledException()中
位于System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThroweException(SocketError错误,CancellationToken CancellationToken)
位于System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16令牌)
在System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.c.b\u 4\u 0(对象状态)
---来自引发异常的上一个位置的堆栈结束跟踪---
at Thrift.Transport.Client.TStreamTransport.ReadAsync(字节[]缓冲区,Int32偏移量,Int32长度,CancellationToken CancellationToken)
at Thrift.Transport.ttTransport.ReadAllAsync(字节[]缓冲区,Int32偏移量,Int32长度,CancellationToken CancellationToken)
at Thrift.Protocol.TBinaryProtocol.ReadI32Async(CancellationToken CancellationToken)
位于Thrift.Protocol.TBinaryProtocol.ReadMessageBeginAsync(CancellationToken CancellationToken)
位于AgentPush.Client.pushEventAsync(PushData数据,CancellationToken CancellationToken)
pushEventAsync似乎在超时后被取消,并抛出TaskCancelledException

System.Threading.Tasks.TaskCanceledException: The operation was canceled.
 ---> System.IO.IOException: Unable to read data from the transport connection: Operation canceled.
 ---> System.Net.Sockets.SocketException (125): Operation canceled
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   
System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowOperationCanceledException()
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token)
   at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location where exception was thrown ---
   at Thrift.Transport.Client.TStreamTransport.ReadAsync(Byte[] buffer, Int32 offset, Int32 length, CancellationToken cancellationToken)
   at Thrift.Transport.TTransport.ReadAllAsync(Byte[] buffer, Int32 offset, Int32 length, CancellationToken cancellationToken)
   at Thrift.Protocol.TBinaryProtocol.ReadI32Async(CancellationToken cancellationToken)
   at Thrift.Protocol.TBinaryProtocol.ReadMessageBeginAsync(CancellationToken cancellationToken)
   at AgentPush.Client.pushEventAsync(PushData data, CancellationToken cancellationToken)
   
我做错了什么? 我可以在代理后面的同一个套接字上使用并行连接吗

我和开发C++代理的家伙一起检查他们的节省服务器确实管理多线程。所以我们在NoDEJS中建立了另一个节省客户的C++服务器。
let clients = [];
for(let i = 0; i < 5; i++){
  let connection = thrift.createConnection("127.0.0.1", 9998, {
    transport, protocol, connect_timeout: 5, timeout: 5, max_attempts: 1  });
  
  let client = thrift.createClient(agentPush, connection);
  connection.on('error', e => console.log("error"))
  connection.on('connected', () => console.log("c"))
  clients.push(client);
}
for(let i = 0; i < 100; i++){
  clients[i%5].pushEvent(data, function(err, res){
    if(err)
    {
      console.log(err);
    }
    else console.log(`succes ${i} with client ${i%5}`);
    //connection.end()
  });
}
let clients=[];
for(设i=0;i<5;i++){
让connection=thrift.createConnection(“127.0.0.1”,9998{
传输,协议,连接超时:5,超时:5,最大尝试次数:1});
让client=thrift.createClient(agentPush,connection);
connection.on('error',e=>console.log(“error”))
connection.on('connected',()=>console.log(“c”))
客户机。推送(客户机);
}
for(设i=0;i<100;i++){
客户端[i%5]。pushEvent(数据,函数(err,res){
如果(错误)
{
控制台日志(err);
}
else console.log(`succes${i}with client${i%5}`);
//connection.end()
});
}
这个NodeJs部分工作正常,所有5个线程都在Thrift服务器上使用

然而,NodeJs从接口生成的代码与C#变体略有不同,并且在writeMessageBegin/writeMessageEnd之后不调用Read方法。 C#异常来自ReadAsync调用

有没有办法解决来自C#的同时呼叫?
最后一点注意:上面的代码是用Thrift v0.13生成的,我已经准备了一个从0.14.1生成的版本,但是我还不能更新其他部分(服务器和操作系统工具),我在那里得到了MaxMessageSize错误…

我只尝试了4个并行请求,而通过我的线程配置允许了5个。还尝试从我的工厂为这几个案例创建新的agentPushClient。这不会改变任何事情。(最初的问题与客户群有关,但这是固定的,与当前问题无关)