最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#使用遠(yuǎn)程服務(wù)調(diào)用框架Apache Thrift

 更新時(shí)間:2022年06月26日 09:04:33   作者:天方  
這篇文章介紹了C#使用遠(yuǎn)程服務(wù)調(diào)用框架Apache Thrift的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Apache Thrift 是 Facebook 實(shí)現(xiàn)的一種高效的、支持多種編程語(yǔ)言的遠(yuǎn)程服務(wù)調(diào)用的框架。和其它RPC框架相比,它主要具有如下連個(gè)特點(diǎn):

  • 高性能。 它采用的是二進(jìn)制序列化,并且用的是長(zhǎng)連接。比傳統(tǒng)的使用XML,SOAP,JSON等短連接的解決方案要快得多。

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

正因?yàn)槿绱?,Thrift對(duì)于高并發(fā)、大數(shù)據(jù)量和多語(yǔ)言的環(huán)境是非常有優(yōu)勢(shì)的,本文就簡(jiǎn)單的介紹一下如何使用它。

使用Thrift和傳統(tǒng)的Corba之類的RPC框架并無(wú)太大差異,主要分為如下三個(gè)部分:

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

  • 將IDL編譯成框架代碼

  • 客戶端使用框架代碼調(diào)用遠(yuǎn)程服務(wù)

  • 服務(wù)端使用框架代碼實(shí)現(xiàn)接口,并提供服務(wù)

和傳統(tǒng)RPC框架一樣,Thrift框架提供數(shù)據(jù)傳輸?shù)姆?wù),服務(wù)端和客戶端只需要關(guān)注業(yè)務(wù)即可;這一系列流程并沒(méi)有多大新穎的地方。

準(zhǔn)備工作:

需要在Thrift官網(wǎng)下載兩個(gè)文件:

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

  • Thrift類庫(kù)。Thrift底層框架,提供了底層的數(shù)據(jù)傳輸服務(wù)。

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

示例項(xiàng)目:

Thrift本身提供了多多種語(yǔ)言的支持,這里示例項(xiàng)目仍以官網(wǎng)的CSharp Tutorial為例來(lái)介紹一下如何在C#中使用Thrift。

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

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()
}

主要就是定義了一個(gè)這樣的接口,提供了四個(gè)接口。以及一些相關(guān)的結(jié)構(gòu)體的定義。定義好接口后,調(diào)用Thrift.exe將其編譯成C#的代碼:

thrift -r --gen csharp tutorial.thrift

編譯完后,會(huì)生成一個(gè)gen-csharp文件夾,里面就是相關(guān)的結(jié)構(gòu)體和接口的定義,和一些框架的實(shí)現(xiàn),具體的后續(xù)再講。這個(gè)文件夾里的文件大部分都是服務(wù)端和客戶端都要用的,為了簡(jiǎn)單起見,大可以建立一個(gè)ShareProject(低版本的VS不支持的話可以建立一個(gè)獨(dú)立的類庫(kù)項(xiàng)目),以方便客戶端和服務(wù)端引用。

客戶端:

首先還是來(lái)看看客戶端代碼(運(yùn)行這段代碼需要加上前面編譯的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);
            }

        }
    }
}

官方的例子簡(jiǎn)化一下后如下:

    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);
    }

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

服務(wù)端:

服務(wù)端示例代碼如下: 

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.");
        }
    }
}

官方代碼基本上包括兩個(gè)部分:接口實(shí)現(xiàn)和服務(wù)的啟動(dòng),簡(jiǎn)化后如下:

    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()
        {
        }
    }

接口實(shí)現(xiàn)依賴于IDL生成的Calculator.Iface接口,這里我就實(shí)現(xiàn)了一個(gè)add接口。再來(lái)看看服務(wù)端 

    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();
    }

服務(wù)端主要的功能就是將剛才的接口作為服務(wù)加載起來(lái),并啟動(dòng)服務(wù),也是比較常規(guī)的做法,沒(méi)有太多需要介紹的地方

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

最后,本文只是一個(gè)簡(jiǎn)單的入門體驗(yàn),如果需要更多信息,請(qǐng)參看Thrift的官方網(wǎng)站。

到此這篇關(guān)于C#使用遠(yuǎn)程服務(wù)調(diào)用框架Apache Thrift的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解讀封送類、結(jié)構(gòu)體和聯(lián)合體實(shí)例

    解讀封送類、結(jié)構(gòu)體和聯(lián)合體實(shí)例

    本文主要介紹了.NETFramework中類、結(jié)構(gòu)體和聯(lián)合體的封送處理,包括類通過(guò)COM互操作封送為接口、結(jié)構(gòu)體通過(guò)StructLayoutAttribute屬性指定布局和封送方式,以及聯(lián)合體通過(guò)StructLayout(LayoutKind.Explicit)和FieldOffset特性精確控制內(nèi)存布局
    2025-01-01
  • 使用C#改善代碼質(zhì)量的技巧和實(shí)踐

    使用C#改善代碼質(zhì)量的技巧和實(shí)踐

    本文將通過(guò)多個(gè)編程技巧和實(shí)踐,展示如何顯著改善代碼質(zhì)量,以 C# 為例,結(jié)合 衛(wèi)語(yǔ)句、枚舉、字典映射、單一職責(zé)原則 等技巧,逐步優(yōu)化代碼,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2025-03-03
  • C#解決引用類型的深度克隆問(wèn)題

    C#解決引用類型的深度克隆問(wèn)題

    本文將給大家介紹如何讓引用類型的對(duì)象復(fù)制以后各自擁有獨(dú)立的內(nèi)存從而實(shí)現(xiàn)一個(gè)對(duì)象值的變化不會(huì)影響別的對(duì)象,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-08-08
  • C#堆排序?qū)崿F(xiàn)方法

    C#堆排序?qū)崿F(xiàn)方法

    這篇文章主要介紹了C#堆排序?qū)崿F(xiàn)方法,實(shí)例分析了C#對(duì)排序的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#中動(dòng)態(tài)數(shù)組用法實(shí)例

    C#中動(dòng)態(tài)數(shù)組用法實(shí)例

    這篇文章主要介紹了C#中動(dòng)態(tài)數(shù)組用法,實(shí)例分析了C#中ArrayList實(shí)現(xiàn)動(dòng)態(tài)數(shù)組的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C# 配置文件app.config 和 web.config詳解

    C# 配置文件app.config 和 web.config詳解

    在 C# 的應(yīng)用開發(fā)中,配置文件就像是幕后的大管家,默默管理著應(yīng)用程序的各種設(shè)置,下面通過(guò)本文介紹 C# 中極為重要的兩個(gè)配置文件,app.config 和 web.config的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2025-04-04
  • C#中在WebClient中使用post發(fā)送數(shù)據(jù)實(shí)現(xiàn)方法

    C#中在WebClient中使用post發(fā)送數(shù)據(jù)實(shí)現(xiàn)方法

    這篇文章主要介紹了C#中在WebClient中使用post發(fā)送數(shù)據(jù)實(shí)現(xiàn)方法,需要的朋友可以參考下
    2014-08-08
  • C#實(shí)現(xiàn)可緩存網(wǎng)頁(yè)到本地的反向代理工具實(shí)例

    C#實(shí)現(xiàn)可緩存網(wǎng)頁(yè)到本地的反向代理工具實(shí)例

    這篇文章主要介紹了C#實(shí)現(xiàn)可緩存網(wǎng)頁(yè)到本地的反向代理工具,實(shí)例分析了C#實(shí)現(xiàn)反向代理的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • c++與c#的時(shí)間轉(zhuǎn)換示例分享

    c++與c#的時(shí)間轉(zhuǎn)換示例分享

    這篇文章主要介紹了C++與C#的時(shí)間轉(zhuǎn)換方法,大家參考使用吧
    2013-12-12
  • C#凈化版WebApi框架的實(shí)現(xiàn)

    C#凈化版WebApi框架的實(shí)現(xiàn)

    這篇文章主要介紹了C#凈化版WebApi框架的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03

最新評(píng)論

长阳| 依安县| 灌阳县| 岳普湖县| 宜章县| 鹰潭市| 阜平县| 沛县| 太保市| 丹巴县| 原平市| 岐山县| 麟游县| 马边| 诸城市| 文安县| 金乡县| 曲沃县| 阜宁县| 竹山县| 彭州市| 开远市| 祥云县| 兰坪| 古交市| 彭泽县| 项城市| 红原县| 台江县| 神木县| 黄梅县| 自贡市| 平顶山市| 墨玉县| 安乡县| 泌阳县| 招远市| 沧州市| 锦州市| 巴楚县| 清流县|