bool A boolean value, true or false
byte A signed byte
i16 A 16-bit signed integer
i32 A 32-bit signed integer
i64 A 64-bit signed integer
double A 64-bit floating point number
string An encoding-agnostic text or binary string
A struct is essentially equivalent to a class in object oriented
programming languages. A struct has a set of strongly typed
fields, each with a unique name identifier. The basic syntax for
defining a Thrift struct looks very similar to a C struct definition.
Fields may be annotated with an integer field identifier (unique to
the scope of that struct) and optional default values. Field identifiers
will be automatically assigned if omitted, though they are strongly
encouraged for versioning reasons discussed later.
Example of struct
|
struct Work { 1: i32 num1 = 0, 2: i32 num2, 3: Operation op, 4: optional string comment, } |
|
struct Example { 1:i32 number=10, 2:i64 bigNumber, 3:double decimals, 4:string name="thrifty" } |
Services are defined using Thrift types. Definition of a service is
semantically equivalent to defining an interface (or a pure virtual
abstract class) in object oriented programming. The Thrift compiler
generates fully functional client and server stubs that implement the
interface. Services are defined as follows:
|
service <name> { <returntype> <name>(<arguments>) [throws (<exceptions>)] ... } |
An example is :
|
service StringCache { void set(1:i32 key, 2:string value), string get(1:i32 key) throws (1:KeyNotFound knf), void delete(1:i32 key) } |
Note : an async modifier keyword may be added to a void function, which will generate code that does not wait for a response from the server.
- Servers and Multithreading
Thrift services require basic multithreading to handle simultaneous
requests from multiple clients
**** Important
Now I will create a RouteServer which supply a “QueryRoute” function , client send Anumber and Bnumber as parameter , server will reply a struct include 2 int and 1 string , how to write this service ?
- First define the struct in thrift file
|
struct Ret { 1: i32 num1 = 0, 2: i32 num2, 3: string routeID, } |
- then define the interface
|
service RouteServer { Ret QueryRoute(1:string Anumber, 2:string Bnumber) } |
Full thrift file is : name is “RouteServer.thrift”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
namespace netcore tutorial # only gen cSharp server and client exception InvalidOperation { 1: i32 whatOp, 2: string why } struct Ret { 1: i32 num1 = 0, 2: i32 num2, 3: string routeID, } service RouteServer { Ret QueryRoute(1:string Anumber, 2:string Bnumber) } |
goto folder : /home/liuyang/thrift-0.11.0/tutorial
run command : rm -r gen-csharp , delete existing folder
then run command : thrift -r –gen csharp RouteServer.thrift
Then goto /home/liuyang/thrift-0.11.0/tutorial/gen-csharp , copy “RouteServer.cs” and “InvalidOperation.cs” and “Ret.cs” to windows machine console application , add to project .
For server side “Program.cs” ,change it to
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Thrift.Server; using Thrift.Transport; namespace RouteService { public class RouteServerHandler : RouteServer.Iface { Dictionary<int, SharedStruct> log; public RouteServerHandler() { log = new Dictionary<int, SharedStruct>(); } public SharedStruct getStruct(int key) { //Console.WriteLine("getStruct({0})", key); return log[key]; } public Ret QueryRoute(string anumber, string bnumber) { Ret r1 = new Ret(); r1.Num1 = 1; r1.Num2 = 2; r1.RouteID = "MaxisRoute"; return r1; } } class Program { static void Main(string[] args) { try { RouteServerHandler handler = new RouteServerHandler(); RouteServer.Processor processor = new RouteServer.Processor(handler); TServerTransport serverTransport = new TServerSocket(9090); //TServer server = new TSimpleServer(processor, serverTransport); TServer server = new TThreadPoolServer(processor, serverTransport); // Use this for a multithreaded server // server = new TThreadPoolServer(processor, serverTransport); Console.WriteLine("Starting the server..."); server.Serve(); } catch (Exception x) { Console.WriteLine(x.StackTrace); } Console.WriteLine("done."); Console.ReadLine(); } } } |
For client “Program.cs” ,change it to
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Thrift; using Thrift.Protocol; using Thrift.Server; using Thrift.Transport; namespace RouteClient { class Program { static void Main(string[] args) { try { TTransport transport = new TSocket("localhost", 9090); TProtocol protocol = new TBinaryProtocol(transport); RouteServer.Client client = new RouteServer.Client(protocol); transport.Open(); try { string s1 = ""; string s2 = ""; Ret r2 = client.QueryRoute(s1, s2); s1 = ""; } finally { transport.Close(); } } catch (TApplicationException x) { Console.WriteLine(x.StackTrace); } } } } |
Now client can call server function and get reply .