package rpc.service; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.util.List; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import com.alibaba.fastjson.JSON; import org.apache.zookeeper.Watcher.Event.KeeperState; import rpc.connector.CommonInvokerFactory; import rpc.connector.Invoker; import rpc.registry.RegisterInfo; public class RpcInvokeHandler implements InvocationHandler, Watcher, Runnable { /* ZooKeeper连接类对象 */ private ZooKeeper zk = null; /* 标识本类对象所代表的监视器的活性 */ private boolean isActive; /* 服务类 */ private Class<?> serviceInterface; /* 存储从ZooKeeper服务器获取的服务列表 */ private List<RegisterInfo> registerInfoList; /* 构造器 */ public RpcInvokeHandler(ZooKeeper zk, Class<?> serviceInterface) { this.isActive = true; this.zk = zk; this.serviceInterface = serviceInterface; } /** * 更新本地的服务列表 * * @throws KeeperException * @throws InterruptedException * @throws UnsupportedEncodingException */ public void getServerList() { // 服务列表 List<String> list = null; try { // 从ZooKeeper服务器获取服务列表,完成后,设置监视器 // 将本类对象作为监视器设置到ZooKeeper服务器 //>>>>>>>>>>>>> list = zk.getChildren("/" + serviceInterface.getName(), this); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } // 服务信息列表存入本地 for(String registerInfoJson : list) { //将拉取的服务信息转化为RegisterInfo对象 RegisterInfo registerInfo = JSON.parseObject(registerInfoJson, RegisterInfo.class); //将RegisterInfo存入serviceList registerInfoList.add(registerInfo); } // 测试代码 // System.out.println("--------------------------------"); // for (String server : serviceList) { // System.out.println( // serviceInterfaceName + " data: " + new String(zk.getData("/" + // serviceInterfaceName + "/" + server, false, null), "UTF-8")); // } } /* * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatchedEvent) */ @Override public void process(WatchedEvent event) { //如果ZooKeeper连接处于正常连接状态 if (event.getState() == KeeperState.SyncConnected) { //对于事件类型 switch (event.getType()) { // 服务器节点更新 case NodeChildrenChanged: try { //如果服务节点更新,则主动拉取服务列表 getServerList(); } catch (Exception e) { e.printStackTrace(); } break; // 服务被删除了,则将整个监视器关闭,使得其失活 case NodeDeleted: close(); break; default: break; } } } // 回调,监视器运行 @Override public void run() { getServerList(); // 阻塞,等监视器关闭时则结束run synchronized (this) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } // 关闭监视器 public void close() { synchronized (this) { this.notify(); } // 使得监视器变为失活状态 isActive = false; } // 检查是否活跃 public boolean isActive() { return isActive; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 这里涉及到服务器选择策略的问题,待优化 //从服务注册信息中获取host和port String host = registerInfoList.get(0).getHost(); int port = registerInfoList.get(0).getPort(); /* 服务器的注册与发现,和服务器的连接,是完全解耦的 */ // 连接服务器,获取invoker Invoker invoker = CommonInvokerFactory.getInstance().get(new InetSocketAddress(host, port)); Object result = invoker.invoke(serviceInterface, method, args); if (result instanceof Throwable) throw (Throwable) result; return result; } }