使用Avro实现RPC简单示例03

接第01部分,本节用来说明Java语言的代码实现。

使用avro生成java代码之后,会生成两个java文件,无论是Client还是Server都要包含这两个文件。

首先是Server端:
1、新建一个java项目,引用以下jar包
avro-1.8.0.jar
avro-ipc-1.8.0.jar
jackson-core-asl-1.9.13.jar
jackson-mapper-asl-1.9.13.jar
netty-3.5.13.Final.jar
slf4j-api-1.7.7.jar
slf4j-simple-1.7.7.jar

2、项目中添加生成的两个java文件。

3、新建一个类MyAvroServer,实现JustATest接口

package com.neohope.avro.test;

import org.apache.avro.AvroRemoteException;

public class MyAvroServer implements JustATest{
    @Override
    public CharSequence SayHelloTo(Person person) throws AvroRemoteException {
        return "Hello "+person.getName();
    }

    @Override
    public int Add(int a, int b) throws AvroRemoteException {
        return a+b;
    }
}

4、修改TestServer.java

package com.neohope.avro.test;

import org.apache.avro.ipc.NettyServer;
import org.apache.avro.ipc.specific.SpecificResponder;

import java.net.InetSocketAddress;
import java.util.Scanner;

public class TestServer {
    public static void main(String[] args) {
        NettyServer server = new NettyServer(new SpecificResponder(
                JustATest.class,
                new MyAvroServer()),
                new InetSocketAddress(1900));
        server.start();
        Scanner sc=new Scanner(System.in);
        sc.nextLine();
        server.close();
    }
}

5、编译运行

然后是Client端:
1、新建一个java项目,引用以下jar包
avro-1.8.0.jar
avro-ipc-1.8.0.jar
jackson-core-asl-1.9.13.jar
jackson-mapper-asl-1.9.13.jar
netty-3.5.13.Final.jar
slf4j-api-1.7.7.jar
slf4j-simple-1.7.7.jar

2、项目中添加生成的两个java文件。

3、修改TestClient.java

package com.neohope.avro.test;

import org.apache.avro.AvroRemoteException;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.specific.SpecificRequestor;
import org.apache.avro.util.Utf8;

import java.io.IOException;
import java.net.InetSocketAddress;

public class TestClient {
    public static void main(String[] args) throws IOException {
        NettyTransceiver client = new NettyTransceiver(new InetSocketAddress("localhost",1900));

        JustATest proxy = (JustATest) SpecificRequestor.getClient(JustATest.class, client);

        Person person = new Person();
        person.setSex(new Utf8("male"));
        person.setName(new Utf8("neohope"));
        person.setAddress(new Utf8("shanghai"));
        System.out.println(proxy.SayHelloTo(person));
        System.out.println(proxy.Add(1,2));

        client.close();
    }
}

4、编译运行

使用Avro实现RPC简单示例02

接第01部分,本节用来说明C#语言的代码实现。

使用avro生成cs代码之后,会生成三个cs文件,Client与Server需要分别包含这三个文件。

首先是Server端:
1、新建一个Console项目,引用Avro程序集中以下几个dll文件
Avro.dll
Avro.ipc.dll
Castle.Core.dll
log4net.dll
Newtonsoft.Json.dll

2、项目中添加生成的以下几个cs文件
JustATest.cs
Person.cs

3、新建一个类MyAvroServer,实现JustATest接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.neohope.avro.test;

namespace TestAvro.com.neohope.avro.test
{
    class MyAvroServer : JustATest
    {
        public override string SayHelloTo(Person person)
        {
            return "Hello " + person.name;
        }

        public override int Add(int a, int b)
        {
            return a + b;
        }
    }
}

4、修改Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using Avro.ipc;
using Avro.ipc.Specific;
using com.neohope.avro.test;
using TestAvro.com.neohope.avro.test;

namespace TestAvro
{
    class Program
    {
        static void Main(string[] args)
        {
            SpecificResponder<JustATest> responder = new SpecificResponder<JustATest>(new MyAvroServer());
            SocketServer server = new SocketServer("localhost", 1900, responder);
            server.Start();

            Console.ReadLine();

            server.Stop();
        }
    }
}

5、编译运行

然后是Client端:
1、新建一个Console项目,引用Avro程序集中以下几个dll文件
Avro.dll
Avro.ipc.dll
Castle.Core.dll
log4net.dll
Newtonsoft.Json.dll

2、项目中添加生成的以下几个cs文件
JustATestCallback.cs
JustATest.cs
Person.cs

3、修改Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Avro.ipc;
using Avro.ipc.Specific;
using com.neohope.avro.test;

namespace TestAvroClient
{
    class Program
    {
        static void Main(string[] args)
        {
            SocketTransceiver transceiver = new SocketTransceiver("localhost", 1900);
            JustATestCallback proxy = SpecificRequestor.CreateClient<JustATestCallback>(transceiver);
            
            Person person = new Person();
            person.sex = "male";
            person.name = "neohope";
            person.address = "shanghai";
            Console.WriteLine(proxy.SayHelloTo(person));
            Console.WriteLine(proxy.Add(1, 2));

            transceiver.Close();
        }
    }
}

4、编译运行

使用Avro实现RPC简单示例01

Avro也是典型CS架构,与ICE、CORBA、Thrift相同,但大家一般不太用其做RPC框架,而多是使用其强大的序列化功能。即使如此,我们也可以将Avro用于RPC通讯,也只需要告诉Avro服务在哪里,需要哪个服务,调用参数是什么,然后就坐等处理结果就好咯。

使用Avro的时候,首先要先下载Avro的开发包,每种序言需要单独下载,都自带编译工具及语言支持包,本例主要用到C#和Java。
Avro

使用新版本Avro的时候,一般显示用IDL语言,定义一个接口描述文件,比如我自己写了一个很简单的接口。
JustATest.avdl

@namespace("com.neohope.avro.test")
protocol JustATest{
  record Person {
    string name;
    int age;
    string sex;
    string address;
  }

  string SayHelloTo(Person person);
  int Add(int a,int b);
}

然后用Avro自带工具,将其翻译为protocol文件
JustATest.avpr

set AVRO_HOME=D:\Build\Avro\avro-java-1.8.0
java -jar %AVRO_HOME%\avro-tools-1.8.0.jar idl JustATest.avdl JustATest.avpr

翻译得到的JustATest.avpr文件如下:

{
  "protocol" : "JustATest",
  "namespace" : "com.neohope.avro.test",
  "types" : [ {
    "type" : "record",
    "name" : "Person",
    "fields" : [ {
      "name" : "name",
      "type" : "string"
    }, {
      "name" : "age",
      "type" : "int"
    }, {
      "name" : "sex",
      "type" : "string"
    }, {
      "name" : "address",
      "type" : "string"
    } ]
  } ],
  "messages" : {
    "SayHelloTo" : {
      "request" : [ {
        "name" : "person",
        "type" : "Person"
      } ],
      "response" : "string"
    },
    "Add" : {
      "request" : [ {
        "name" : "a",
        "type" : "int"
      }, {
        "name" : "b",
        "type" : "int"
      } ],
      "response" : "int"
    }
  }
}

然后,用工具分别编译为java及c#语言

#java
set AVRO_HOME=D:\Build\Avro\avro-java-1.8.0
java -jar %AVRO_HOME%\avro-tools-1.8.0.jar compile protocol JustATest.avpr avpr

#c#
avrogen -p JustATest.avpr avpr-cs