91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#怎么使用遠程服務調用框架Apache?Thrift

發布時間:2022-07-07 10:25:37 來源:億速云 閱讀:216 作者:iii 欄目:開發技術

這篇“C#怎么使用遠程服務調用框架Apache Thrift”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C#怎么使用遠程服務調用框架Apache Thrift”文章吧。

Apache Thrift 是 Facebook 實現的一種高效的、支持多種編程語言的遠程服務調用的框架。和其它RPC框架相比,它主要具有如下連個特點:

  • 高性能。 它采用的是二進制序列化,并且用的是長連接。比傳統的使用XML,SOAP,JSON等短連接的解決方案要快得多。

  • 多語言支持。 它對提供了對C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk等多種常用語言的支持

正因為如此,Thrift對于高并發、大數據量和多語言的環境是非常有優勢的,本文就簡單的介紹一下如何使用它。

使用Thrift和傳統的Corba之類的RPC框架并無太大差異,主要分為如下三個部分:

  • 使用IDL定義提供的服務:主要用于服務接口和數據傳輸對象(DTO)并且有一套自己的語法, Thrift中命名為thirft文件,并且有一套自己的語法。

  • 將IDL編譯成框架代碼

  • 客戶端使用框架代碼調用遠程服務

  • 服務端使用框架代碼實現接口,并提供服務

和傳統RPC框架一樣,Thrift框架提供數據傳輸的服務,服務端和客戶端只需要關注業務即可;這一系列流程并沒有多大新穎的地方。

準備工作:

需要在Thrift官網下載兩個文件:

  • IDL編譯工具。官方本身提供了Windows的exe版本:thrift-0.9.2.tar.gz

  • Thrift類庫。Thrift底層框架,提供了底層的數據傳輸服務。

下載完后,由于Thrift類庫是以源碼形式提供的,因此需要自己編譯。為了簡單,這里以C#為例,打開 "\lib\csharp\src\Thrift.sln" 工程文件,直接編譯即可生成Thrift.dll文件。官方說.net版本.net 3.5及以上即可。

示例項目:

Thrift本身提供了多多種語言的支持,這里示例項目仍以官網的CSharp Tutorial為例來介紹一下如何在C#中使用Thrift。

首先下載接口定義文件 tutorial.thrift 和shared.thrift 。官方的文檔中加了一大堆注釋,實際上還是比較簡單的,主體部分如下:

service Calculator extends shared.SharedService
{
   void ping(),
   i32 add(1:i32 num1, 2:i32 num2),
   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
   oneway void zip()
}

主要就是定義了一個這樣的接口,提供了四個接口。以及一些相關的結構體的定義。定義好接口后,調用Thrift.exe將其編譯成C#的代碼:

thrift -r --gen csharp tutorial.thrift

編譯完后,會生成一個gen-csharp文件夾,里面就是相關的結構體和接口的定義,和一些框架的實現,具體的后續再講。這個文件夾里的文件大部分都是服務端和客戶端都要用的,為了簡單起見,大可以建立一個ShareProject(低版本的VS不支持的話可以建立一個獨立的類庫項目),以方便客戶端和服務端引用。

客戶端:

首先還是來看看客戶端代碼(運行這段代碼需要加上前面編譯的Thrift.dll和編譯idl文件生成的一堆C#代碼):

using System;
using Thrift;
using Thrift.Protocol;
using Thrift.Server;
using Thrift.Transport;

namespace CSharpTutorial
{
    public class CSharpClient
    {
        public static void Main()
        {
            try
            {
                TTransport transport = new TSocket("localhost", 9090);
                TProtocol protocol = new TBinaryProtocol(transport);
                Calculator.Client client = new Calculator.Client(protocol);

                transport.Open();
                try
                {
                    client.ping();
                    Console.WriteLine("ping()");

                    int sum = client.add(1, 1);
                    Console.WriteLine("1+1={0}", sum);

                    Work work = new Work();

                    work.Op = Operation.DIVIDE;
                    work.Num1 = 1;
                    work.Num2 = 0;
                    try
                    {
                        int quotient = client.calculate(1, work);
                        Console.WriteLine("Whoa we can divide by 0");
                    }
                    catch (InvalidOperation io)
                    {
                        Console.WriteLine("Invalid operation: " + io.Why);
                    }

                    work.Op = Operation.SUBTRACT;
                    work.Num1 = 15;
                    work.Num2 = 10;
                    try
                    {
                        int diff = client.calculate(1, work);
                        Console.WriteLine("15-10={0}", diff);
                    }
                    catch (InvalidOperation io)
                    {
                        Console.WriteLine("Invalid operation: " + io.Why);
                    }

                    SharedStruct log = client.getStruct(1);
                    Console.WriteLine("Check log: {0}", log.Value);

                }
                finally
                {
                    transport.Close();
                }
            }
            catch (TApplicationException x)
            {
                Console.WriteLine(x.StackTrace);
            }

        }
    }
}

官方的例子簡化一下后如下:

    using (TTransport transport = new TSocket("localhost", 9090))
    using (TProtocol protocol = new TBinaryProtocol(transport))
    using (Calculator.Client client = new Calculator.Client(protocol))
    {
        transport.Open();
        int sum = client.add(1, 1);
        Console.WriteLine("1+1={0}", sum);
    }

主要就設計到了三個類:TTransport、TProtocol和Calculator.Client,其中TTransport、Tprotocol是用于傳輸控制的,和業務無關,是在Thrift.dll中定義的。而Calculator.Client則是客戶端的Proxy,用于執行RPC,和業務相關,是由idl文件編譯生成。客戶端無需編寫代碼,即可擁有RPC能力。(這個特效基本上所有RPC框架都具有)

服務端:

服務端示例代碼如下: 

using System;
using System.Collections.Generic;
using Thrift.Server;
using Thrift.Transport;

namespace CSharpTutorial
{
    public class CalculatorHandler : Calculator.Iface
    {
        Dictionary<int, SharedStruct> log;

        public CalculatorHandler()
        {
            log = new Dictionary<int, SharedStruct>();
        }

        public void ping()
        {
            Console.WriteLine("ping()");
        }

        public int add(int n1, int n2)
        {
            Console.WriteLine("add({0},{1})", n1, n2);
            return n1 + n2;
        }

        public int calculate(int logid, Work work)
        {
            Console.WriteLine("calculate({0}, [{1},{2},{3}])", logid, work.Op, work.Num1, work.Num2);
            int val = 0;
            switch (work.Op)
            {
                case Operation.ADD:
                    val = work.Num1 + work.Num2;
                    break;

                case Operation.SUBTRACT:
                    val = work.Num1 - work.Num2;
                    break;

                case Operation.MULTIPLY:
                    val = work.Num1 * work.Num2;
                    break;

                case Operation.DIVIDE:
                    if (work.Num2 == 0)
                    {
                        InvalidOperation io = new InvalidOperation();
                        io.What = (int)work.Op;
                        io.Why = "Cannot divide by 0";
                        throw io;
                    }
                    val = work.Num1 / work.Num2;
                    break;

                default:
                    {
                        InvalidOperation io = new InvalidOperation();
                        io.What = (int)work.Op;
                        io.Why = "Unknown operation";
                        throw io;
                    }
            }

            SharedStruct entry = new SharedStruct();
            entry.Key = logid;
            entry.Value = val.ToString();
            log[logid] = entry;

            return val;
        }

        public SharedStruct getStruct(int key)
        {
            Console.WriteLine("getStruct({0})", key);
            return log[key];
        }

        public void zip()
        {
            Console.WriteLine("zip()");
        }
    }

    public class CSharpServer
    {
        public static void Main()
        {
            try
            {
                CalculatorHandler handler = new CalculatorHandler();
                Calculator.Processor processor = new Calculator.Processor(handler);
                TServerTransport serverTransport = new TServerSocket(9090);
                TServer server = new TSimpleServer(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.");
        }
    }
}

官方代碼基本上包括兩個部分:接口實現和服務的啟動,簡化后如下:

    public class CalculatorHandler : Calculator.Iface
    {
        public void ping()
        {
        }

        public int add(int n1, int n2)
        {
            return n1 + n2;
        }

        public int calculate(int logid, Work work)
        {
            throw new InvalidOperation();
        }

        public SharedStruct getStruct(int key)
        {
            return new SharedStruct();
        }

        public void zip()
        {
        }
    }

接口實現依賴于IDL生成的Calculator.Iface接口,這里我就實現了一個add接口。再來看看服務端 

    static void Main(string[] args)
    {
        CalculatorHandler handler = new CalculatorHandler();
        Calculator.Processor processor = new Calculator.Processor(handler);

        TServerTransport serverTransport = new TServerSocket(9090);
        TServer server = new TSimpleServer(processor, serverTransport);

        Console.WriteLine("Starting the server...");
        server.Serve();
    }

服務端主要的功能就是將剛才的接口作為服務加載起來,并啟動服務,也是比較常規的做法,沒有太多需要介紹的地方

從這個Demo來看,主要過程和其它RPC框架的流程倒也沒有太大區別。一個比較出彩的地方是Thrift是提供了原生的.net運行庫的(前面編譯的Thrift.dll),作為一個跨語言的框架不用Pinvoke非常給力,給部署帶來不少方便。本來高性能才是它的主要特點,后續有空再測試一下。

以上就是關于“C#怎么使用遠程服務調用框架Apache Thrift”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

柘城县| 葵青区| 会同县| 乌审旗| 贵州省| 安溪县| 桂东县| 新乡县| 手机| 临泽县| 惠东县| 博白县| 文登市| 景谷| 嵊泗县| 皮山县| 黑龙江省| 合水县| 忻州市| 拉萨市| 旅游| 兰考县| 凭祥市| 荥经县| 喀喇沁旗| 临澧县| 绥江县| 蓝田县| 南川市| 兰州市| 伊宁县| 紫金县| 文登市| 丰台区| 宕昌县| 黄石市| 醴陵市| 五台县| 芦山县| 闽清县| 萨迦县|