자바 Rpc 구현

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;

public class RpcFramework {

	public static void export(final Object service, final Class interfaceClazz, int port) throws Exception {

		System.out.println("Export service " + service.getClass().getName() + " on port " + port);

		ServerSocket server = new ServerSocket(port);
		for (;;) {
			final Socket socket = server.accept();

			new Thread(new Runnable() {
				public void run() {
					try {
						ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
						String interfaceName = input.readUTF();
						String methodName = input.readUTF();
						Class>[] parameterTypes = (Class>[]) input.readObject();
						Object[] arguments = (Object[]) input.readObject();
						ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
						Method method = service.getClass().getMethod(methodName, parameterTypes);
						Object result = method.invoke(service, arguments);
						output.writeObject(result);

					} catch (Exception e) {
						throw new RuntimeException(e.toString());
					}
				}
			}).start();
		}
	}

	@SuppressWarnings("unchecked")
	public static  T refer(final Class interfaceClass, final String host, final int port) throws Exception {

		System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
		return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class>[] { interfaceClass },
				new InvocationHandler() {

					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						Socket socket = new Socket(host, port);

						ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

						output.writeUTF(interfaceClass.getName());
						output.writeUTF(method.getName());
						output.writeObject(method.getParameterTypes());
						output.writeObject(args);

						ObjectInputStream input = new ObjectInputStream(socket.getInputStream());

						Object result = input.readObject();
						if (result instanceof Throwable) {
							throw (Throwable) result;
						}
						return result;
					}
				});
	}
}

RpcFramework. java 파일 은 가장 핵심 적 인 처리 프로 세 스 입 니 다. 서버 에서 export () 방법 으로 외부 노출 서 비 스 를 호출 하고 클 라 이언 트 가 refer () 방법 으로 원 격 프로 세 스 를 호출 합 니 다. 사실은 동적 에이전트 대상 을 생 성하 고 이 동적 에이전트 대상 의 invoke () 방법 을 호출 합 니 다. 소스 코드 를 보면 invoke 방법 에서 자바 의 BIO 를 사용 하여 서버 를 연결 하 는 것 을 볼 수 있 습 니 다.또한 호출 할 인터페이스, 방법, 파라미터 등 을 서버 에 전송 합 니 다.서버 는 이 매개 변 수 를 통 해 구체 적 인 대상 을 호출 하면 결 과 를 되 돌려 줍 니 다.
공통 인터페이스:
public interface HelloService {

    String hello();

    String hello(String name);

}

서버 구현 클래스:
public class HelloServiceImpl implements HelloService {

    public String hello() {
        return "Hello";
    }

    public String hello(String name) {
        return "Hello," + name;
    }

}

서버 노출 서비스 종류:
public class RpcProvider {

    public static void main(String[] args) throws Exception {
        HelloService service = new HelloServiceImpl();
        RpcFramework.export(service, HelloService.class, 9000);
    }

}

클 라 이언 트 시작 클래스:
이 코드 사례 는 자바 개발 자 들 이 rpc 호출 절 차 를 이해 하 는 데 도움 을 줄 수 있 습 니 다.

좋은 웹페이지 즐겨찾기