u011511086的专栏

好记性不如烂笔头。 站在岸上学不会游泳。 泉水挑不干,知识学不完。 三天不念口生,三天不做手生。 用珠宝装扮自己,不如用知识充实自己。 花盆里长不出参天松,庭院里练不出千里马...

C# RPC远程方法调用框架thrift

首先项目创建windows控制台程序,项目里面引用
这里写图片描述

写这篇文章时用的是thrift-csharp版本0.10.0
项目结构
这里写图片描述

服务端代码

using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Thrift.Server;

namespace ThriftServer
{
    public class TestServer : ChatService.Iface
    {
        public List<string> GetList(string function2_arg1, int function2_arg2, List<string> function2_arg3)
        {
            List<string> list = new List<string>();
            Parallel.ForEach(function2_arg3, m =>
            {
                list.Add($"{ function2_arg1},年龄 { function2_arg2},正在:{m}");
            });
            return list;
        }

        public string Say(string thing)
        {
            return thing + "测试数据";
        }

    }
}

using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Thrift;
using Thrift.Protocol;
using Thrift.Server;
using Thrift.Transport;

namespace ThriftServer
{
    class Program
    {
        static void Main(string[] args)
        {
            //TcpListener tcpListener = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"),7988);
            //TServerTransport transport =new TServerSocket(tcpListener);
            int port = 15789;
            TServerTransport transport = new TServerSocket(port);

            TestServer serverIfac = new TestServer();
            TProcessor processor = new ChatService.Processor(serverIfac);
            TServer server = new TThreadPoolServer(processor, transport);

            Task.Run(() =>
            {                
                try
                {
                    Console.WriteLine("服务启动,端口" + port);
                    server.Serve();                   
                }
                catch (Exception ex)
                {
                    Console.WriteLine("启动服务异常:" + ex.Message);
                }
            });

            Console.ReadKey();

        }
    }
}

客户端代码

using Thrift.Protocol;
using Thrift.Transport;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Client
{
    class ClientDo
    {
        public static string GetServerData(string words, Common.ChatService.Client client)
        {
            //var transport = new TSocket("localhost", 15789);
            //var protocol = new TBinaryProtocol(transport);
            //var client = new  Common.ChatService.Client(protocol);
            //transport.Open();

            string allBooks = client.Say(words); // Actual Thrift call           
            return allBooks;
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Thrift.Protocol;
using Thrift.Transport;

namespace Client
{
    class Program
    {

        static void Main(string[] args)
        {

            var transport = new TSocket("localhost", 15789);
            var protocol = new TBinaryProtocol(transport);
            var client = new Common.ChatService.Client(protocol);
            transport.Open();

            ////测试一
            //Task.Run(() =>
            //{
            //    while (true)
            //    {
            //        Random m = new Random();
            //        int ronum = m.Next(10000);
            //        string words = ronum + "说" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            //        string backMsg = ClientDo.GetServerData(words, client);
            //        Console.WriteLine(backMsg);
            //        Task.Delay(1000).Wait();
            //    }
            //});

            //测试二
            List<string> data = new List<string>();
            data.Add("吃饭");
            data.Add("看书");
            data.Add("跑路");
            List<string> list=  client.GetList("欧阳修", 77, data);
            Parallel.ForEach(list,m=> {
                Console.WriteLine(m);
            });

            //transport.Close();

            Console.ReadKey();
        }

    }
}

然后是ChatService类是生成的,需要用到thrift-0.11.0.exe
怎么生成?
首先打开windows的控制台,先进入到thrift-0.11.0.exe所在目录,然后执行命令,这个ChatService.cs是通过命令生成的
命令生成cs文件:
thrift-0.11.0.exe -gen csharp demo-interface.thrift

生成的thrift模板文件里面,需要定义自己所需的方法,参考代码,比如文件:demo-interface.thrift

namespace * Common

service ChatService
{
  string Say(1: string thing),

  list<string> GetList(
    1: string function2_arg1,
    2: i32 function2_arg2,
    3: list<string> function2_arg3
  ),
}

执行命令之后会在当前目录生成一个文件夹gen-csharp,里面包含生成的类文件ChatService.cs,将此文件粘贴到项目Common里面即可
上图:
这里写图片描述

测试效果
这里写图片描述

这里有模板文件参考代码,文件名break1.thrift

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

//Thrift Method removed from service base.

namespace cpp test

//constants
const i32 const1 = 123;
const double const2 = 23.3;
const map<string,string> const3 = {"hello":"world", "thrift":"audit"};

//Exception
exception test_exception1 {
    1: i32 code;
    2: string json;
}
exception test_exception2 {
    1: i32 code;
    2: string json;
}

//Enums

enum test_enum1 {
    enum1_value0 = 0,
    enum1_value1 = 1,
    enum1_value2 = 2,
    enum1_value5 = 5,
    enum1_value7 = 7,
    enum1_value8 = 8
}

enum test_enum2 {
    enum2_value0 = 0,
    enum2_value1 = 1,
    enum2_value2 = 2,
    enum2_value3 = 3
}

enum test_enum3 {
    enum3_value1 = 0,
    enum3_value2 = 1
}

struct test_struct1 {
    1: i16 struct1_member1,
    2: i32 struct1_member2,
    3: i64 struct1_member3,
    4: double struct1_member4 = 2.5,
    5: string struct1_member5 = "Audit test",
    6: bool struct1_member6,
    7: byte struct1_member7,
    8: binary struct1_member8,
    9: test_enum1 struct1_member9
}

struct test_struct2 {
    1: list<i16> struct2_member1,
    2: list<i32> struct2_member2,
    3: list<i64> struct2_member3= [23, 32],
    4: list<double> struct2_member4,
    5: list<string> struct2_member5,
    6: list<bool> struct2_member6,
    7: list<byte> struct2_member7,
    8: list<binary> struct2_member8,
    9: list<test_enum1> struct2_member9
}

struct test_struct3 {
    1: map<i16, i32> struct3_member1 = {1:2, 3:4},
    2: map<i64, double> struct3_member2 = {10:1.1, 20:2.1},
    3: map<string, bool> struct3_member3,
    4: map<byte, test_enum1> struct3_member4,
    5: map<test_enum2, test_enum3 > struct3_member5,
    7: map<double, string> struct3_member7
}

struct test_struct4 {
    1: i32 struct4_member1,
    2: optional i32 struct4_member2
}

struct test_struct5{
    1: double struct5_member1,
    2: string struct5_member2 = "Thrift Audit Test"
}
struct test_struct6 {
    1: i32 struct6_member1,
    2: required i32 struct6_member2
}

service base {
    oneway void base_oneway(
        1: i32 arg1),

    void base_function1(
        1: i16 function1_arg1,
        2: i32 function1_arg2,
        3: i64 function1_arg3,
        4: double function1_arg4,
        5: string function1_arg5,
        6: bool function1_arg6,
        7: test_enum1 function1_arg7,
        8: test_struct1 function1_arg8),

    void base_function2(
        1: list<i16> function2_arg1,
        2: list<i32> function2_arg2,
        3: list<i64> function2_arg3,
        4: list<double> function2_arg4,
        5: list<string> function2_arg5,
        6: list<bool> function2_arg6,
        7: list<byte> function2_arg7,
        8: list<test_enum1> function2_arg8,
        9: list<test_struct1> function2_arg9) throws (1:test_exception2 e),

}

service derived1 extends base {

    test_enum1 derived1_function1(
        1: i64 function1_arg1,
        2: double function1_arg2,
        3: test_enum1 function1_arg3) throws (1:test_exception2 e),

    i64 derived1_function2(
        1: list<i64> function2_arg1,
        2: list<double> function2_arg2,
        3: list<string> function2_arg3,
        4: list<byte> function2_arg4,
        5: list<test_enum1> function2_arg5) throws (1:test_exception2 e),

    double derived1_function3(
        1: string function3_arg1,
        2: bool function3_arg2) throws (1:test_exception2 e),

    string derived1_function4(
        1: string function4_arg1,
        2: bool function4_arg2) throws (1:test_exception2 e),


    bool derived1_function5(
        1: map<i64, double> function5_arg1,
        2: map<string, bool> function5_arg2,
        3: map<test_enum1, test_enum2> function5_arg3) throws (1:test_exception2 e),

    test_struct1 derived1_function6(
        1: double function6_arg1) throws (1:test_exception2 e),
}

service derived2 extends base {

    list<i32> derived2_function1(
        1: i32 function1_arg1) throws (1:test_exception2 e),

    list<test_enum1> derived2_function2(
        1:i64 function2_arg2) throws (1:test_exception2 e),

    list<test_struct1> derived2_function3(
        1:double function3_arg1) throws(1:test_exception2 e),

    map<double, string> derived2_function4(
        1:string function4_arg1) throws(1:test_exception2 e),

    map<test_enum1, test_enum2> derived2_function5(
        1:bool function5_arg1) throws(1:test_exception2 e),

    map<test_struct1, test_struct2> derived2_function6(
        1:bool function6_arg1) throws(1:test_exception2 e),

}

demo下载地址
https://download.csdn.net/download/u011511086/10355584

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011511086/article/details/79978292
文章标签: thrift 远程RPC框架
个人分类: Rpc框架
上一篇ASP.NET MVC中使用依賴注入Autofac容器
下一篇C# Hprose轻量级、跨语言、跨平台的面向对象的高性能远程动态通讯中间件
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭