Non-original, original address
Directory
Preface 1
Preparing for Work 1
A simple applet 3
1. Preparation Work 3
2 Mini-Test Sledgehammer 5
Digging deeper 12
1. Architecture Diagram 12
2 Data Type 15
3 Protocol 16
4 Transport Layer 16
5 Service-side type 16
This article mainly references the reference material 22
Thrift Study Summary
APAHCE Thrift is an efficient framework for Facebook to implement remote service calls that support multiple languages. This paper introduces the architecture and development of Apache Thrift from the perspective of C # developers, and gives the corresponding C # instance for different transport protocols and service types, and briefly introduces the implementation of thrift asynchronous client.
Objective
Thrift is a scalable, cross-lingual service development framework developed by Fackbook, which has been open source and joined the Apache project. Thrift main function is: through the custom interface definition Language (IDL), you can create RPC-based client and service-side service code. The generation of data and service code is implemented through the thrift built-in code generator. Thrift's cross-language body now, it can generate C + +, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cocoa, JavaScript, node. js, Smalltalk, OCaml , Delphi and other language code, and they can communicate transparently.
Thrift Code Generator Windows edition
Http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.2/thrift-0.9.2.exe
Thrift Source
Http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.2/thrift-0.9.2.tar.gz
Preparatory work
This article first Li Zilai a simple explanation of the use of thrift and how to build thrift services. First of all you need to download Thrift code generator and source, such as on the connection.
With the code generation tool, you also need to thrift the class library file so that we can invoke it. Open the download good source code, find the solution under THRIFT-0.9.2\LIB\CSHARP\SRC,
Then open with VS2013, you can see the following structure
A simple little program
1. Preparatory work
Finish the preparatory work can formally begin to write a small program, feel thrift. To create a simple Hello service, write the script file Hello.thrift according to the Thrift Syntax specification as follows:
Listing 1. Hello.thrift
Namespace CSharp Hellothrift.interface
Service helloservice{
String hellostring (1:string para)
I32 Helloint (1:i32 para)
BOOL Helloboolean (1:bool para)
void Hellovoid ()
String Hellonull ()
}
Then open cmd to switch to the Thrift Code generation tool's storage directory, enter the following command on the command line Thrift-gen CSharp Hello.thrift
The Code generation tool automatically generates C # code for the defined interface script in the current directory, and the resulting code directory is as follows
Open Directory to see the generated service definition file
There are five methods that define the service HelloService, each containing a method name, a parameter list, and a return type. Each parameter consists of a parameter ordinal, a parameter type, and an argument name. Thrift is a specific implementation of the descriptive language of IDL (Interface Definition Language). Therefore, the above service description file is written in IDL syntax. Using the Thrift tool to compile the Hello.thrift, the corresponding HelloService.cs file is generated. The file contains the interface definition of the service HelloService described in the Hello.thrift file, the Helloservice.iface interface, and the underlying communication details of the service invocation, including the client's invocation logic Helloservice.client and server-side processing logic helloservice.processor for building client and server-side functionality.
2 small trial Sledgehammer
You can begin to feel the charm of thrift after you get ready to work. Open vs Create a blank solution named Hellothrift. Create a Lib folder under the solution root and place the Thrift.dll file generated in the preparation into the Lib folder. In the solution sub-set up two console programs and a class library, the console program named Hellothrift.client and Hellothrift.server, the class library named Thrift.interface. Client, server, and interface refer to the Thrift.dll file in the Lib folder, respectively, and import the HelloService files generated in the preparation to the interface class library. Client and server refer to interface respectively. The concrete results are as shown.
After completing the reference import work, create a class named Myhelloservice on the service side, implementing the Helloservice.iface interface with the following code:
Listing 2. Myhelloservice
Using System;
Using Hellothrift.interface;
Namespace Hellothrift.server
{
public class MyHelloService:HelloService.Iface
{
<summary>
Only one parameter returns a method with a value of type string
</summary>
<param name= "para" >string type parameters </param>
<returns> return value is String type </returns>
public string hellostring (string para)
{
Console.WriteLine ("The client called the Hellostring method");
return para;
}
<summary>
A method that returns a value of type int with only one argument
</summary>
<param name= "Para" ></param>
<returns> return value is int type </returns>
public int helloint (int para)
{
Console.WriteLine ("The client called the Helloint method");
return para;
}
<summary>
There is only one bool type parameter and a method that returns a bool type
</summary>
<param name= "Para" ></param>
<returns> return value is bool type </returns>
public bool Helloboolean (bool para)
{
Console.WriteLine ("The client called the Helloboolean method");
return para;
}
<summary>
Returns the method that executes as empty
</summary>
public void Hellovoid ()
{
Console.WriteLine ("The client called the Hellovoid method");
Console.WriteLine ("HelloWorld");
}
<summary>
A method that returns a null value without parameters
</summary>
<returns> return value is null</returns>
public string Hellonull ()
{
Console.WriteLine ("The client called the Hellonull method");
return null;
}
}
}
Create a server-side implementation code that passes Myhelloservice as a specific processor to the Thrift server with the following code:
Listing 3. Hellothrift.server
Using System;
Using Hellothrift.interface;
Using Thrift;
Using Thrift.protocol;
Using Thrift.server;
Using Thrift.transport;
Namespace Hellothrift.server
{
Class Program
{
<summary>
Start the service side
</summary>
<param name= "args" ></param>
static void Main (string[] args)
{
Try
{
Set the service port to 8080
Tserversocket servertransport = new Tserversocket (8080);
Set up a transport protocol factory
Tbinaryprotocol.factory Factory = new Tbinaryprotocol.factory ();
Implementation of correlation processor and service
Tprocessor processor = new Helloservice.processor (new Myhelloservice ());
Creating a service-side object
Tserver Server = new Tthreadpoolserver (processor, Servertransport, new Ttransportfactory (), factory);
Console.WriteLine ("Service is listening on port 8080");
}
catch (Ttransportexception ex)//catch exception information
{
Print exception information
Console.WriteLine (ex. Message);
}
}
}
}
Create the client implementation code, call the Hellothrift.client to access the server side of the logical implementation, the code is as follows:
Listing 3. Hellothrift.client
Using System;
Using Hellothrift.interface;
Using Thrift.protocol;
Using Thrift.transport;
Namespace Hellothrift.client
{
Class Program
{
static void Main (string[] args)
{
Try
{
Set the service port port number and address
Ttransport transport=new tsocket ("localhost", 8080);
Transport. Open ();
Set the transport protocol as a binary transport protocol
Tprotocol protocol=new Tbinaryprotocol (transport);
Creating Client Objects
Helloservice.client client=new helloservice.client (protocol);
Methods to invoke the service side
Console.WriteLine (client. Hellostring ("Hellothrift"));
Console.readkey ();
}
catch (Ttransportexception e)
{
Console.WriteLine (E.message);
}
}
}
}
The above code calls the Hellostring method on the server side, and the server returns the incoming transfer value, and the client prints the data returned by the server. Okay, after you've finished the code, modify the program's startup item order, right-click to resolve the guard, start the project, select the Multi-boot project, and set the client and server to start. F5 Start the program, witness the moment of wonder, then the client will not print out the results?
Client Invoke result
Service side Display Request result
About other methods This article no longer demonstrates that the call is the same, only the method that returns null is thrown by the client, because C # does not know what this is. The other method return values are normal. Here is a brief discussion of how the framework communicates. (Just copy and paste)
Digging deeper
So the question comes, mining technology which strong, Beijing, China to find the network.
The Thrift contains a complete stack structure for building the client and server side. Depicts the overall architecture of the Thrift.
1. Architecture diagram
, the yellow part of the figure is the user-implemented business logic, the brown part is based on the Thrift definition of the service interface profile generated by the client and server-side code framework, the red part is based on the Thrift file generated code to achieve data read and write operations. Red section below is the Thrift transport system, protocol, and underlying I/O communication, using Thrift to easily define a service and choose a different transport protocol and transport layer without having to regenerate the code.
The Thrift server contains the infrastructure for binding protocols and transport layers, which provides blocking, non-blocking, single-threaded, and multithreaded modes to run on the server, but because of the limitations of the C # language, the service side of the C # implementation has no nonblocking mode and can be called with Winform/webform.
The service-side and client-specific invocation processes are as follows:
The diagram shows the process of Helloserviceserver startup and the response of the server when the service is called by the client. We can see that after the program calls the Tthreadpoolserver server method, the server enters the blocking listening state, which is blocked on the Tserversocket accept method. When a message is received from the client, the server initiates a new thread to process the message request and the original thread enters the blocking state again. In the new thread, the server reads the message content through the TBINARYPROTOCOL protocol, invokes the Helloserviceimpl hellovoid method, and writes the results back to the client in Hellovoid_result.
The figure shows the process of helloserviceclient invoking the service and processing the result after receiving the return value from the server side. As we can see, the program calls the Hello.client Hellovoid method, in the Hellovoid method, sends the call request to the service through the Send_hellovoid method, through the RECV_ The Hellovoid method receives the result returned by the service after the request is processed.
2 data types
Thrift scripts can define data types that include the following types:
Basic type:
BOOL: Boolean, True or FALSE, corresponding to C # bool
A byte:8-bit signed integer that corresponds to the C # byte
A i16:16-bit signed integer that corresponds to the short of C #
I32:32-bit signed integer corresponding to C # int
A i64:64-bit signed integer that corresponds to the C # long
double:64 bit floating-point number, corresponding to C # double
String: Unknown encoded text or binary string, corresponding to C # string
struct type:
struct: Defines a common object, similar to a struct definition in C, which is an entity class in C #
Container type:
List: List<t> ordered set of C # correspondence
Set: A set that corresponds to C # 's hashset<t> unordered but not repeatable
Map: Dictionary<tkey,tvalue> Key-value pair collection for C #, key cannot be duplicated
Exception type:
Exception: corresponding to C # exception
Service Type:
Service: The class of the corresponding services
3 protocol
Thrift can let the user choose the type of transmission communication protocol between client and server, divide the transmission protocol into text and binary (binary) transmission protocol, in order to save bandwidth, improve transmission efficiency, and generally use binary type transmission protocol as the majority, Sometimes a text type-based protocol is used, depending on the actual requirements in the project/product. Common protocols include the following: binaryprotocol--binary encoding format for data transmission, tcompactprotocol--efficient, dense binary encoding format for data transfer, tjsonprotocol--using JSON Data encoding protocol.
4 Transport Layer
tsocket--using blocking I/O is the most common pattern, due to the inability of the C # language to use non-blocking synchronous transfers and non-blocking asynchronous transfers
5 Service-side type
The tsimpleserver--single-threaded server side uses standard blocking-type I/O using standard blocking i/o,tthreadpoolserver--multithreaded servers. Because of the limitations of the C # language, the non-blocking multithreaded service side cannot be used. The general development uses the blocking multi-threaded server to be able. another.
Through the small trial sledgehammer initially felt the charm of the thrift Framework, through a simple analysis of the basic principles of the thrift framework, then how to combine the three-tier architecture for complex applications? So we'll do it again, using the three-tier architecture +thrift+web form for crud, this time the client is no longer a console program but a Web application to invoke.
First of all, be prepared to define the script that is needed for this case, and the script that defines it is as follows:
Listing 4. User.thrift
The above script defines an entity named user, which has five attributes, and the service defines 7 methods of action. Because the thrift framework does not have a definition of datetime type data, it can only be replaced by a string type. Then create good entity classes and service interfaces as required, import the various files needed in the solution and create a three-tier architecture. After the specific creation of the program structure as shown, because of the length of the reasons for this is not how to import files and create a three-tier framework, detailed procedures refer to the source code, this example focuses on how to invoke the service side of the Web client method to operate the remote data.
After building the framework, you need to specify the address and port number of the server in the client configuration file, as follows
<appSettings>
<!--service port number--
<add key= "Port" value= "8080"/>
<!--server address---
<add key = "host" value= "localhost"/>
</appSettings>
After setting up the profile information, define the client implementation in the Thriftclinetfactory class in the code, as shown below
Using System;
Using System.Configuration;
Using Thrift.protocol;
Using Thrift.transport;
Using Thriftapp.common;
Namespace Thriftapp.webclient
{
public static Class Thriftclinetfactory
{
public static userservice.client Createthriftclient ()
{
Get the host address in the configuration file
String hostName = configurationmanager.appsettings["Host"];
Get the service port number
int port = Convert.ToInt32 (configurationmanager.appsettings["Port"]);
Set the transport port and server address
Ttransport transport = new Tsocket (hostName, Port);
Setting the transport protocol to Binary Protocol
Tprotocol protocol = new Tbinaryprotocol (transport);
Create a client object and bind the transport protocol
Userservice.client Client = new userservice.client (protocol);
Open the transport port
Transport. Open ();
Returns the Client object
return client;
}
}
}
After defining the factory class created by the client, we can create the client object directly from the factory and invoke the method on the server side. Create a WebForm page on the Web server, name test, drag a repeater control in the foreground page, and define the template with the following code.
<%@ page language= "C #" autoeventwireup= "true" codebehind= "Test.aspx.cs" inherits= "ThriftApp.WebClient.Test"%>
<! DOCTYPE html>
<meta http-equiv= "Content-type" content= "text/html; Charset=utf-8 "/>
<title></title>
<link href= "Bootstrap/css/bootstrap.min.css" rel= "stylesheet"/>
<script src= "Bootstrap/js/jquery-2.1.3.js" ></script>
<script src= "Bootstrap/js/bootstrap.min.js" ></script>
<body>
<form id= "Form1" runat= "Server" >
<div>
<asp:repeater id= "Repeater1" runat= "Server" >
<HeaderTemplate>
<table class= "Table table-bordered" >
<tr>
<th> numbering </th>
<th> User name </th>
<th> Password </th>
<th> Email </th>
<th> Registration Time </th>
</tr>
</HeaderTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
<ItemTemplate>
<tr>
<td><% #Eval ("Id")%></td>
<td><% #Eval ("UserName")%></td>
<td><% #Eval ("Userpass")%></td>
<td><% #Eval ("Email")%></td>
<td><% #Eval ("Regtime")%></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
To bind the data source in the background page, the code is as follows:
Creating Client Objects
using (var client = thriftclinetfactory.createthriftclient ())
{
Get all user information, specify the data source
Repeater1.datasource = client. Getalluser ();
Binding Data
Repeater1.databind ();
}
Set the startup item for the solution, set both the Web client and the server as the startup item, and you will see the following results when you start F5
More specific additions and deletions to check the operation, please refer to the source code. No refresh crud result diagram attached
This article mainly refers to the reference material
Apache Thrift-Scalable cross-language service development Framework http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/
Thrift Study Summary