Hadoop之RPC简单实现

来源:互联网 发布:nightowl软件 编辑:程序博客网 时间:2024/05/07 07:33

1.前言

   RPC 远程调用,就是一台机器上的某个进程要调用另一台机器上的某个进程的方法,中间通信传输的就是类似于“方法名,参数1,参数2…..”这样的信息,

两个远程主机,客户端肯定不可能直接调用远程服务端的相关类和方法,借助动态代理,其两端必须同实现同一个接口,当客户端调用某个对象的某个方法时,就通过序列化把要调用的对象和方法,以及参数通过流的形式传到服务端,服务端通过反序列化,拿到要调用的对象和方法以及参数,在服务端进行调用,然后把结果再通过流的形式传到客户端,这样就好像,一切都在客户端执行似的,在这里我也只是简单的实现一下,

其大体流程如下:


2.涉及技术

  2.1 java动态代理

  2.2 socket 编程

3. 代码实现

客户端:

接口:

public interface Person {


public  static final long versionID=10L;
public String eat(String name);
}

具体实现类:



public class PersonImpl implements Person {


@Override
public String eat(String name) {
return name +"在吃饭";
}


}

 

客户端调用服务端代码:

public class SocketClient {



public void getConnection(){
try {
Socket  socket=new Socket("127.0.0.1",8111);
//构建输入流 读取服务器端的发过来的信息
InputStream inputStream = socket.getInputStream();
//包装输入流
InputStreamReader isr=new InputStreamReader(inputStream);

BufferedReader br=new BufferedReader(isr);

//构造输出流
PrintWriter pw=new PrintWriter(socket.getOutputStream());
//从控制台 读取数据
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));


System.out.println("请输入:");

String readLine2 = sin.readLine();
pw.println(readLine2);
pw.flush();
  String readLine = br.readLine();

System.out.println("服务端响应数据:--->"+readLine);

inputStream.close();
pw.close();
socket.close();
System.out.println("客户端退出");


} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
SocketClient sc=new SocketClient();
sc.send();
}


public void  send()
{

SocketProxy sp=new SocketProxy(new PersonImpl());
Person p=(Person)Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, sp);
//在这里调用 p中方式 实际就是为了启动 反射的invoke方法  实际执行的是服务端中的方法
p.eat("");
}
}




class SocketProxy implements InvocationHandler
{
private Object target;
  public SocketProxy(Object target)
  {
 this.target=target;
  }


@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("客户端尝试连接服务端.......");
//在客户端调用方法 实际就是为了调用反射 从而去链接服务端 拿到服务端的返回结果
new SocketClient().getConnection();
return null;
}



}

  

服务端:

接口:

public interface Person {
public  static final long versionID=10L;


public String eat(String name);
}


实现类也是具体执行的类:

public class PersonImpl implements Person {


@Override
public String eat(String name) {
return name +"在吃饭";
}


}

服务端回应客户端的代码:


public void acceptRequest()
{


try {
//监听一个端口号
ServerSocket server=new ServerSocket(8111);
Socket accept=null;
InputStream inputStream=null;
OutputStream outputStream =null;
//写数据
   PrintWriter pw=null;
//不断的读取客户端发来的数据
while(true)
{
accept = server.accept();//输入阻塞时的 不接到客户端 就不向下执行
 //得到输入流读取客户端数据
    inputStream = accept.getInputStream();
//输入流的包装类
InputStreamReader isr=new InputStreamReader(inputStream);
BufferedReader br=new BufferedReader(isr);

//构造输出流 发送数据
outputStream = accept.getOutputStream();
//写数据
    pw=new PrintWriter(outputStream);


String readLine = br.readLine();
System.out.println("客户端发来的数据:-->"+readLine);
String responseMsg=request(readLine);
//服务端发送数据
pw.println(responseMsg);
pw.flush();
if("ok".equals(readLine))
{
break;
}
}
outputStream.close();
inputStream.close();
accept.close();
server.close();
System.out.println("服务器退出");


} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


public String  request(String name)
{
InvocationServer is =new InvocationServer(new PersonImpl());
Person p=(Person)Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, is);
//客户端的调用实际执行的是 这个方法
 return   p.eat(name);

}
public static void main(String[] args) {

SocketServer ss=new SocketServer();
System.out.println("服务器启动.....");
ss.acceptRequest();


}
}




class InvocationServer implements InvocationHandler
{

private Object target;

public InvocationServer(Object target)
{
this.target=target;
}


@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(target, args);
}
}


本节结束

1 0
原创粉丝点击