/// <summary> /// Ping. /// </summary> public void Ping() { var pool = ConnectionPoolManager.GetPool(this.Host, this.Port, this.Timeout); ThriftSConnection connection = null; try { connection = pool.Borrow(); var xrequest = new ThriftSRequest(); xrequest.Headers = new Dictionary <string, string>(); xrequest.ClientHostName = Environment.MachineName; xrequest.ClientIP = connection.LocalAddress.ToString(); connection.Client.Ping(xrequest); } catch (TTransportException exception) { pool.ReportError(connection, exception); throw; } catch (TProtocolException exception) { pool.ReportError(connection, exception); throw; } catch (SocketException exception) { pool.ReportError(connection, exception); throw; } catch (IOException exception) { pool.ReportError(connection, exception); throw; } finally { pool.Release(connection); } }
/// <summary> /// Invokes the specified message. /// </summary> /// <param name="message">The message.</param> /// <returns>IMessage.</returns> public override IMessage Invoke(IMessage message) { var mcm = (IMethodCallMessage)message; IMethodReturnMessage returnMessage = null; if (mcm.MethodBase.IsDefined(typeof(ThriftSOperationAttribute), false) == false) { throw new ThriftSException(string.Format("Missing ThriftSOperationAttribute in '{0}.{1}'.", this.ServiceName, mcm.MethodName)); } object returnValue = null; var stopwatch = new Stopwatch(); string invokeDesc = string.Format("调用{0}契约的{1}方法", this.ServiceName, mcm.MethodName); // 构造请求 var srequest = new ThriftSRequest() { ServiceName = this.ServiceName, MethodName = Utils.GetMethodName((MethodInfo)mcm.MethodBase), Headers = new Dictionary <string, string>(), Parameters = new List <ThriftSParameter>() }; srequest.Uri = string.Format("thrift://{0}:{1}/{2}/{3}", this.Host, this.Port, this.ServiceShortName, srequest.MethodName); srequest.Version = Utils.Version; srequest.ClientPid = this.ClientPid; srequest.ClientHostName = this.ClientHostName; srequest.ClientRuntime = ".NET " + Environment.Version.ToString(); try { // 计时开始 stopwatch.Start(); if (mcm.Args != null) { for (var i = 0; i < mcm.Args.Length; i++) { var argument = mcm.Args[i]; ThriftSParameter parameter = null; if (argument == null) { parameter = new ThriftSParameter() { Index = (sbyte)i, Name = string.Empty, Type = string.Empty, Compression = ThriftSCompression.None, ContentType = ContentTypes.Binary, HasValue = false }; } else { parameter = new ThriftSParameter() { Index = (sbyte)i, Name = string.Empty, Type = string.Empty, Compression = ThriftSCompression.None, ContentType = ContentTypes.Thrift, HasValue = true, Value = ThriftSerializer.Serialize(argument) }; } // 大于10K开启压缩 if (parameter.Value != null && parameter.Value.Length > 10 * 1024) { parameter.Value = Utils.GzipCompress(parameter.Value); parameter.Compression = ThriftSCompression.Gzip; } srequest.Parameters.Add(parameter); } } ThriftSResponse sresponse = null; try { var xpool = ConnectionPoolManager.GetPool(this.Host, this.Port, this.Timeout); ThriftSConnection xconnection = null; TimeSpan connectTookTime = TimeSpan.MinValue; try { DateTime beginConnectTime = DateTime.Now; xconnection = xpool.Borrow(); connectTookTime = beginConnectTime - DateTime.Now; if (string.IsNullOrEmpty(this.ClientIP)) { this.ClientIP = xconnection.LocalAddress.ToString(); } srequest.ClientIP = this.ClientIP; sresponse = xconnection.Client.Process(srequest); } catch (SocketException exception) { xpool.ReportError(xconnection, exception); this.HandleException("SocketException", invokeDesc, srequest, exception); } catch (IOException exception) { xpool.ReportError(xconnection, exception); var socketException = exception.InnerException as SocketException; if (socketException != null) { this.HandleException("SocketException", invokeDesc, srequest, socketException); } this.HandleException("IOException", invokeDesc, srequest, exception); } catch (TTransportException exception) { xpool.ReportError(xconnection, exception); // 5秒以内的timeout认为是服务器积极拒绝. if (exception.Message.StartsWith("Connect timed out") && connectTookTime.TotalSeconds < 5) { // 处理异常 this.HandleException( "TTransportException", invokeDesc, srequest, new TTransportException(exception.Type, "Service unavailable.")); } else { this.HandleException("TTransportException", invokeDesc, srequest, exception); } } catch (TProtocolException exception) { xpool.ReportError(xconnection, exception); this.HandleException("TProtocolException", invokeDesc, srequest, exception); } finally { // 内部Try可以更快的释放连接。 xpool.Release(xconnection); } // 非void且result非空 if (sresponse != null && sresponse.Result != null) { // 解压 if (sresponse.Result.Compression == ThriftSCompression.Gzip) { sresponse.Result.Data = Utils.GzipUnCompress(sresponse.Result.Data); } if (sresponse.Result.ContentType == ContentTypes.Thrift) { returnValue = ThriftSerializer.Deserialize( ((MethodInfo)mcm.MethodBase).ReturnType, sresponse.Result.Data); } else { throw new NotSupportedException(string.Format("Not supported content type: {0}", sresponse.Result.ContentType)); } } returnMessage = new ReturnMessage(returnValue, null, 0, mcm.LogicalCallContext, mcm); } catch (TApplicationException tapplicationException) { var info = string.Format("tapplication exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException(info + tapplicationException.Message, tapplicationException); returnMessage = new ReturnMessage(exception, mcm); } catch (BadRequestException badRequestException) { var info = string.Format("Bad request exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException( info + badRequestException.ErrorMessage, info + Environment.NewLine + badRequestException.ErrorMessage); // 远端异常使用ReturnMessage包装 returnMessage = new ReturnMessage(exception, mcm); } catch (InternalServerException internalServerException) { var info = string.Format("Server internal exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException( info + internalServerException.ErrorMessage, info + Environment.NewLine + internalServerException.ErrorDescription); returnMessage = new ReturnMessage(exception, mcm); } catch (InvocationException invocationException) { var info = string.Format("Server invocation exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException( info + invocationException.ErrorMessage, info + Environment.NewLine + invocationException.ErrorDescription); returnMessage = new ReturnMessage(exception, mcm); } catch (Exception exception) { this.HandleException("Exception", invokeDesc, srequest, exception); } } finally { stopwatch.Stop(); } return(returnMessage); }