以后补上
hadoop版本:hadoop-2.7.3
package rpc.server;
import org.apache.hadoop.ipc.VersionedProtocol;
/**
* Created by leboop on 2019/1/18.
*/
public interface MyInterface extends VersionedProtocol {
//版本号变量名必须是versionID
long versionID = 1L;
int add(int a, int b);
}
(1)MyInterface继承Hadoop的VersionedProtocol接口
(2)在MyInterface接口中定义版本号变量versionID,注意变量名必须是versionID,原因是RPC类的getProtocolVersion方法是通过字符串versionID获取版本号的,如下:
static public long getProtocolVersion(Class> protocol) {
if (protocol == null) {
throw new IllegalArgumentException("Null protocol");
}
long version;
ProtocolInfo anno = protocol.getAnnotation(ProtocolInfo.class);
if (anno != null) {
version = anno.protocolVersion();
if (version != -1)
return version;
}
try {
Field versionField = protocol.getField("versionID");
versionField.setAccessible(true);
return versionField.getLong(protocol);
} catch (NoSuchFieldException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
(3)在MyInterface中自定义了一个方法,用于计算两个整数的和。
package rpc.server;
import org.apache.hadoop.ipc.ProtocolSignature;
import java.io.IOException;
/**
* Created by leboop on 2019/1/18.
*/
public class MyInterfaceImpl implements MyInterface {
public int add(int a, int b) {
System.out.println("*********Server*********");
return a + b;
}
public long getProtocolVersion(String protocol, long clientVersion) throws IOException {
System.out.println("MyInterface.versionID=" + MyInterface.versionID);
return MyInterface.versionID;
}
public ProtocolSignature getProtocolSignature(String protocol, long clientVersion, int clientMethodsHash) throws IOException {
return new ProtocolSignature();
}
}
(1)MyInterfaceImpl实现了MyInterface接口的add()方法,为了待会能够看出RPC服务端的add()方法被调用,打印了一些信息;
(2)MyInterfaceImpl实现了VersionedProtocol接口的getProtocolVersion和getProtocolSignature方法,分别返回协议接口的版本号和协议签名;
package rpc.server;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.Server;
import java.io.IOException;
/**
* Created by leboop on 2019/1/18.
*/
public class ServerMain {
public static final String IP = "192.168.189.112";
public static final int PORT = 1234;
public static void main(String[] args) {
MyInterfaceImpl proxy = new MyInterfaceImpl();
RPC.Builder builder = new RPC.Builder(new Configuration());
builder.setBindAddress(IP);
builder.setPort(PORT);
builder.setProtocol(MyInterface.class);
builder.setInstance(new MyInterfaceImpl());
Server server = null;
try {
server = builder.build();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Server正在运行……");
server.start();
}
}
(1)服务端绑定了IP地址和对应的端口号,其中IP地址是部署该服务端程序的Linux的IP地址,可以使用localhost,端口可以任意定义。
(2)通过server.start()启动服务端。
客户端代码相对比较简单,只有一个主程序,如下:
package rpc.client;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import rpc.server.MyInterface;
import java.io.IOException;
import java.net.InetSocketAddress;
/**
* Created by leboop on 2019/1/18.
*/
public class MyClient {
public static final String IP = "192.168.189.112";
public static final int PORT = 1234;
public static void main(String[] args) {
InetSocketAddress inetSocketAddress = new InetSocketAddress(IP, PORT);
try {
// 注意:这里传入的版本号需要与代理保持一致
MyInterface proxy = RPC.waitForProxy(
MyInterface.class, MyInterface.versionID, inetSocketAddress,
new Configuration());
int result = proxy.add(10, 25);
System.out.println("10+25=" + result);
RPC.stopProxy(proxy);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
(1)注意这里IP地址和端口号必须与服务端设定的一致;
(2)客户端向服务端传递了两个整数:10和25,通过调用服务端的RPC协议接口实现类的add方法计算出他们的和,并将结果返回给客户端。
将服务端代码打成可执行jar包,上传至Linux服务器上,执行
java -jar jar包
启动服务端,如图:
服务端已经启动成功,现在在Windows本地启动客户端,此时会在服务端输出add方法被调用的信息,如图:
同时将计算结果返回给客户端输出,如图: