定义
一开始AB应用在同一台机器上,是本地调用
现在分到两个地方上了
server这边有很多服务A,B,HelloService
现在要把这些服务放到服务注册中心去,客户端调用的时候直接去跟服务的注册中心去就可以直接调用
注册中心用map来实现
客户端和服务端通过socket链接
- 客户端如果要调用helloService,,而服务端需要通过该字符串"HelloService"解析出该字符串代表的接口的一切信息(通过反射技术)
- socket
- 服务端需要根据客户端的不同请求,返回不同的借口类型
客户端就要接受到不同的接口类型(通过动态代理)
按照流程来写代码
1.服务端start()开启服务端服务
服务端首先需要一些内部成员:
public class ServerCenter implements Sever{
//这个用来存放服务名和对应的接口
private static HashMap<String,Class> serviceRegister = new HashMap<>();
private static int port;
public ServerCenter(int port){
this.port = port;
}
}
然后开启
public void start() throws IOException{
ServerSocket server = new ServerSocket();
//绑定端口
server.bind(new InetSocketAddress(port));
//接受客户端的请求
server.accept();
}
2.Client获取代表服务端接口的动态代理对象
服务端要告诉客户端接口的名字和 IP地址端口号()
//参数是:1.客户端请求的服务的接口,socket的地址(即ip+port)
public static <T> T getRemoteProxyObj(Class serviceInterface,InetSocketAddress addr){
/*
返回一个动态代理即可
newProxyInstance需要三个参数:
1.类加载器:需要代理哪个类,比如helloService
2.接口:需要代理的对象具备哪些功能
3.一个invocationHandler,采用匿名内部类实现
*/
return (T)Proxy.newProxyInstance(
serviceInterface.getClassLoader(),//服务类接口的类加载器
new Class<?>[] {
serviceInterface},//服务类的接口(可能有很多个接口所以使用数组)
new InvocationHandler(){
//匿名内部类
@Override
//只需要实现这一个方法即可
/*
三个参数:
1.proxy是代理的对象
2.method是需要代理的方法
3.args是方法参数列表
*/
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
//1.客户端向服务端发送请求,请求某一个具体的接口
Socket socket = new Socket();
socket.connect(addr);//addr = ip + port
ObjectOutputStream output = newObjectOutputStream(socket.getOutputStream());
//发送:接口名,方法名,方法参数,参数类型
output.writeUTF(serviceInterface.getName());
output.writeUTP(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
}
}
)
}
服务端接收到客户端连接及请求,处理该请求
public void start() throws IOException{
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress(port));
Socket socket = server.accept();
/*----------从这里开始-----------*/
ObjectInputStream input