0
点赞
收藏
分享

微信扫一扫

Thrift架构~windows下安装和Hello World及编码引起的错误

ITWYY 2022-10-11 阅读 166

最近开始正式接触Thrift架构,很牛B的技术,它被apache收纳了,属于开源中的一员,呵呵。

概念:

Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开源项目,对于当时 的facebook来说创造thrift是为了解决facebook系统中各系统间大数据量的传 输通信以及系统之间语言环境不同需要跨平台的特性。所以thrift可以支持多种程序语言,例如:  C++, C#, Cocoa, Erlang, Haskell, Java, Ocami, Perl, PHP, Python, Ruby, Smalltalk. 在多种不同的语言之间通信thrift可以作为二进制的高性能的通讯中间件,支持数据(对象)序列化和多种类型的RPC服务。Thrift适用于程序对程 序静态的数据交换,需要先确定好他的数据结构,他是完全静态化的,当数据结构发生变化时,必须重新编辑IDL文件,代码生成,再编译载入的流程,跟其他 IDL工具相比较可以视为是Thrift的弱项,Thrift适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输相对于JSON和 xml无论在性能、传输大小上有明显的优势。

下面看一下windows下的安装与使用。

Thrift目前最高0.9.1,地址:​​http://archive.apache.org/dist/thrift/​​

注意,我们要把exe和tar文件都下载下来,exe用来编译你的thrift中间语言,而tar解压后,我们可以看到csharp,php,java,js等多种开发语言的实例代码,对我们很有帮助的,​​下载最新版​​

下载之后,我们把exe文件可以放在C盘,建个Thrift目录,把它放入,然后可以配置一下环境变量,如图:

Thrift架构~windows下安装和Hello World及编码引起的错误_#if

然后,我们就可以进行thrift中间语言的开发了,之所以说它是中间语言,是因为它不是最终我们要使用的,而需要将它进行编译之后,才生成我们的目标语言,就像C语言,它在编译时也是生成obj目标语言,然后再二次编译最终生成exe文件,它们的道理是一样的,

我们的thrift语言,通过thrift程序可以生成多种编程语言的源代码。

编码问题

使用VS建立一个thrift文件后,在进行编译时出现了问题,最后找到答案,原来是编码问题,最后使用记事本把编码被为ANSI就可以正常编译了。

Thrift架构~windows下安装和Hello World及编码引起的错误_#if_02

Hello world程序代码:

namespace csharp HelloThriftspace

exception Xception {
1: i32 errorCode,
2: string message
}

service HelloThrift{
void HelloWorld() throws (1:Xception ex)
}

编译代码:

thrift --gen csharp hellothrift.thrift

结果:namespace表示文件夹的所在地,方法,结构,枚举都是以文件形式存在的

Thrift架构~windows下安装和Hello World及编码引起的错误_#endif_03

 

生成的C#代码:

Xception.cs

namespace HelloThriftspace
{

#if !SILVERLIGHT
[Serializable]
#endif
public partial class Xception : TException, TBase
{
private int _errorCode;
private string _message;

public int ErrorCode
{
get
{
return _errorCode;
}
set
{
__isset.errorCode = true;
this._errorCode = value;
}
}

public string Message
{
get
{
return _message;
}
set
{
__isset.message = true;
this._message = value;
}
}


public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset {
public bool errorCode;
public bool message;
}

public Xception() {
}

public void Read (TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop) {
break;
}
switch (field.ID)
{
case 1:
if (field.Type == TType.I32) {
ErrorCode = iprot.ReadI32();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
case 2:
if (field.Type == TType.String) {
Message = iprot.ReadString();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
}

public void Write(TProtocol oprot) {
TStruct struc = new TStruct("Xception");
oprot.WriteStructBegin(struc);
TField field = new TField();
if (__isset.errorCode) {
field.Name = "errorCode";
field.Type = TType.I32;
field.ID = 1;
oprot.WriteFieldBegin(field);
oprot.WriteI32(ErrorCode);
oprot.WriteFieldEnd();
}
if (Message != null && __isset.message) {
field.Name = "message";
field.Type = TType.String;
field.ID = 2;
oprot.WriteFieldBegin(field);
oprot.WriteString(Message);
oprot.WriteFieldEnd();
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
}

public override string ToString() {
StringBuilder sb = new StringBuilder("Xception(");
sb.Append("ErrorCode: ");
sb.Append(ErrorCode);
sb.Append(",Message: ");
sb.Append(Message);
sb.Append(")");
return sb.ToString();
}

}

}

View Code

HelloThrift.cs

namespace HelloThriftspace
{
public partial class HelloThrift {
public interface Iface {
void HelloWorld();
#if SILVERLIGHT
IAsyncResult Begin_HelloWorld(AsyncCallback callback, object state);
void End_HelloWorld(IAsyncResult asyncResult);
#endif
}

public class Client : IDisposable, Iface {
public Client(TProtocol prot) : this(prot, prot)
{
}

public Client(TProtocol iprot, TProtocol oprot)
{
iprot_ = iprot;
oprot_ = oprot;
}

protected TProtocol iprot_;
protected TProtocol oprot_;
protected int seqid_;

public TProtocol InputProtocol
{
get { return iprot_; }
}
public TProtocol OutputProtocol
{
get { return oprot_; }
}


#region " IDisposable Support "
private bool _IsDisposed;

// IDisposable
public void Dispose()
{
Dispose(true);
}


protected virtual void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
{
if (iprot_ != null)
{
((IDisposable)iprot_).Dispose();
}
if (oprot_ != null)
{
((IDisposable)oprot_).Dispose();
}
}
}
_IsDisposed = true;
}
#endregion



#if SILVERLIGHT
public IAsyncResult Begin_HelloWorld(AsyncCallback callback, object state)
{
return send_HelloWorld(callback, state);
}

public void End_HelloWorld(IAsyncResult asyncResult)
{
oprot_.Transport.EndFlush(asyncResult);
recv_HelloWorld();
}

#endif

public void HelloWorld()
{
#if !SILVERLIGHT
send_HelloWorld();
recv_HelloWorld();

#else
var asyncResult = Begin_HelloWorld(null, null);
End_HelloWorld(asyncResult);

#endif
}
#if SILVERLIGHT
public IAsyncResult send_HelloWorld(AsyncCallback callback, object state)
#else
public void send_HelloWorld()
#endif
{
oprot_.WriteMessageBegin(new TMessage("HelloWorld", TMessageType.Call, seqid_));
HelloWorld_args args = new HelloWorld_args();
args.Write(oprot_);
oprot_.WriteMessageEnd();
#if SILVERLIGHT
return oprot_.Transport.BeginFlush(callback, state);
#else
oprot_.Transport.Flush();
#endif
}

public void recv_HelloWorld()
{
TMessage msg = iprot_.ReadMessageBegin();
if (msg.Type == TMessageType.Exception) {
TApplicationException x = TApplicationException.Read(iprot_);
iprot_.ReadMessageEnd();
throw x;
}
HelloWorld_result result = new HelloWorld_result();
result.Read(iprot_);
iprot_.ReadMessageEnd();
if (result.__isset.ex) {
throw result.Ex;
}
return;
}

}
public class Processor : TProcessor {
public Processor(Iface iface)
{
iface_ = iface;
processMap_["HelloWorld"] = HelloWorld_Process;
}

protected delegate void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);
private Iface iface_;
protected Dictionary<string, ProcessFunction> processMap_ = new Dictionary<string, ProcessFunction>();

public bool Process(TProtocol iprot, TProtocol oprot)
{
try
{
TMessage msg = iprot.ReadMessageBegin();
ProcessFunction fn;
processMap_.TryGetValue(msg.Name, out fn);
if (fn == null) {
TProtocolUtil.Skip(iprot, TType.Struct);
iprot.ReadMessageEnd();
TApplicationException x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, "Invalid method name: '" + msg.Name + "'");
oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));
x.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
return true;
}
fn(msg.SeqID, iprot, oprot);
}
catch (IOException)
{
return false;
}
return true;
}

public void HelloWorld_Process(int seqid, TProtocol iprot, TProtocol oprot)
{
HelloWorld_args args = new HelloWorld_args();
args.Read(iprot);
iprot.ReadMessageEnd();
HelloWorld_result result = new HelloWorld_result();
try {
iface_.HelloWorld();
} catch (Xception ex) {
result.Ex = ex;
}
oprot.WriteMessageBegin(new TMessage("HelloWorld", TMessageType.Reply, seqid));
result.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
}

}


#if !SILVERLIGHT
[Serializable]
#endif
public partial class HelloWorld_args : TBase
{

public HelloWorld_args() {
}

public void Read (TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop) {
break;
}
switch (field.ID)
{
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
}

public void Write(TProtocol oprot) {
TStruct struc = new TStruct("HelloWorld_args");
oprot.WriteStructBegin(struc);
oprot.WriteFieldStop();
oprot.WriteStructEnd();
}

public override string ToString() {
StringBuilder sb = new StringBuilder("HelloWorld_args(");
sb.Append(")");
return sb.ToString();
}

}


#if !SILVERLIGHT
[Serializable]
#endif
public partial class HelloWorld_result : TBase
{
private Xception _ex;

public Xception Ex
{
get
{
return _ex;
}
set
{
__isset.ex = true;
this._ex = value;
}
}


public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset {
public bool ex;
}

public HelloWorld_result() {
}

public void Read (TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop) {
break;
}
switch (field.ID)
{
case 1:
if (field.Type == TType.Struct) {
Ex = new Xception();
Ex.Read(iprot);
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
}

public void Write(TProtocol oprot) {
TStruct struc = new TStruct("HelloWorld_result");
oprot.WriteStructBegin(struc);
TField field = new TField();

if (this.__isset.ex) {
if (Ex != null) {
field.Name = "Ex";
field.Type = TType.Struct;
field.ID = 1;
oprot.WriteFieldBegin(field);
Ex.Write(oprot);
oprot.WriteFieldEnd();
}
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
}

public override string ToString() {
StringBuilder sb = new StringBuilder("HelloWorld_result(");
sb.Append("Ex: ");
sb.Append(Ex== null ? "<null>" : Ex.ToString());
sb.Append(")");
return sb.ToString();
}

}

}
}

View Code

感觉生成的代码还是比较麻烦的,希望thrift在以后的产品中,对这块解决的好一点,呵呵。

下一讲我们将进行客户端与服务器环境的搭建。

 

 

 

作者:仓储大叔,张占岭,
荣誉:微软MVP



举报

相关推荐

0 条评论