All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinygroup.rmi.impl.RmiServerImpl Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2012-2016, www.tinygroup.org ([email protected]).
 *
 *  Licensed under the GPL, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.gnu.org/licenses/gpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.tinygroup.rmi.impl;

import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import org.tinygroup.rmi.ConnectTrigger;
import org.tinygroup.rmi.RmiServer;

import java.io.Serializable;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class RmiServerImpl extends UnicastRemoteObject implements
        RmiServer {

    private static final long serialVersionUID = -8847587819458611248L;

    private final static Logger LOGGER = LoggerFactory
            .getLogger(RmiServerImpl.class);

    int port = DEFAULT_RMI_PORT;
    String hostName = "localhost";
    int remotePort = DEFAULT_RMI_PORT;
    String remoteHostName = "";

    // private ValidateThread validateThread = new ValidateThread();
    Registry registry = null;
    Registry remoteRegistry = null;
    RmiServer remoteServer = null;
    Map registeredRemoteObjectMap = new HashMap();
    Map registeredLocalObjectMap = new HashMap();
    HeartThread heartThread = new HeartThread();
    Map> triggers = new HashMap>();

    public RmiServerImpl() throws RemoteException {
        this("localhost", DEFAULT_RMI_PORT);
    }

    public RmiServerImpl(int port) throws RemoteException {
        this("localhost", port);
    }

    public RmiServerImpl(String hostName, int port) throws RemoteException {
        this(hostName, port, null, 0);
    }

    public RmiServerImpl(String hostName, int port, String remoteHostName,
                         int remotePort) throws RemoteException {
        if (hostName != null && !"".equals(hostName)) {
            this.hostName = hostName;
        }
        this.port = port;
        this.remoteHostName = remoteHostName;
        this.remotePort = remotePort;

        try {
            getRemoteRegistry();
            bindThis();
            if (remoteRegistry != null) {
                startHeart();
            }

        } catch (RemoteException e) {
            LOGGER.errorMessage("连接远端服务器时发生异常", e);
            startHeart();
        }
        getRegistry();

    }

    private void startHeart() {
        heartThread.start();
    }

    private void bindThis() throws RemoteException {
        if (remoteServer != null) {
            remoteServer.registerRemoteObject(this,
                    getKeyName(hostName, port + ""));

        }
    }

    public Registry getRegistry() throws RemoteException {
        if (registry == null) {
            try {
                registry = LocateRegistry.getRegistry(hostName, port);
                registry.list();
            } catch (Exception e) {
                try {
                    registry = LocateRegistry.createRegistry(port);
                } catch (RemoteException e1) {
                    throw new RuntimeException(e1);
                }
            }
        }
        try {
            registry.rebind(getKeyName(hostName, port + ""), this);
        } catch (AccessException e) {
            throw new RuntimeException(e);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }

        return registry;
    }

    public Registry getRemoteRegistry() throws RemoteException {

        if (remoteHostName == null || "".equals(remoteHostName)) {
            return null;
        }
        System.setProperty("java.rmi.server.hostname", remoteHostName);
        remoteRegistry = LocateRegistry.getRegistry(remoteHostName, remotePort);
        try {
            remoteServer = (RmiServer) remoteRegistry.lookup(getKeyName(
                    remoteHostName, remotePort + ""));
        } catch (NotBoundException e) {
            LOGGER.errorMessage("获取远端服务器:" + remoteHostName + "时出现异常,该对象未曾注册", e);
            throw new RuntimeException("获取远端服务器:" + remoteHostName
                    + "时出现异常,该对象未曾注册", e);
        }
        return remoteRegistry;
    }

    public void stop() throws RemoteException {
        stopHeart();
        unexportObjects();
        stopLocalRegistry();
    }

    public void stopLocalRegistry() throws RemoteException {
        if (registry != null) {
            UnicastRemoteObject.unexportObject(this, true);
        }
    }

    private void stopHeart() {
        heartThread.stop();
    }

    public void addTrigger(ConnectTrigger trigger) throws RemoteException {
        String type = trigger.getType();
        if (triggers.containsKey(type)) {
            triggers.get(type).add(trigger);
        } else {
            List list = new ArrayList();
            list.add(trigger);
            triggers.put(type, list);
        }
    }

    private void reReg() {

        try {
            remoteServer = (RmiServer) remoteRegistry.lookup(getKeyName(
                    remoteHostName, remotePort + ""));
        } catch (NotBoundException e) {
            LOGGER.errorMessage("获取远端服务器:" + remoteHostName + "时出现异常,该对象未曾注册", e);
        } catch (RemoteException e1) {
            LOGGER.errorMessage("连接远端服务器:" + remoteHostName + "失败", e1);
        }

        for (String name : registeredLocalObjectMap.keySet()) {
            try {
                remoteServer.registerRemoteObject(
                        registeredLocalObjectMap.get(name), name);
            } catch (RemoteException e) {
                LOGGER.errorMessage("向远端服务器重新注册对象name:{}时出现异常", e, name);
            }
        }
        LOGGER.logMessage(LogLevel.DEBUG, "将本地对象重新注册至远端服务器完成");
        try {
            bindThis();
        } catch (RemoteException e) {
            LOGGER.errorMessage("向远端服务器重新绑定当前服务器信息时出现异常", e);
        }
    }

    private boolean checkRemoteHasThis() {
        try {
            Object o = remoteServer.getObject(getKeyName(hostName, port + ""));
            return o != null;
        } catch (Exception e) {
            return false;
        }
    }

    public void registerLocalObject(Remote object, String name)
            throws RemoteException {
        try {
            LOGGER.logMessage(LogLevel.DEBUG, "开始注册本地对象:{}", name);
            System.setProperty("java.rmi.server.hostname", hostName);
            registeredLocalObjectMap.put(name, object);
            if (object instanceof UnicastRemoteObject) {
                registry.rebind(name, object);
                if (remoteServer != null) {
                    remoteServer.registerRemoteObject(object, name);
                }
            } else {
                Remote stub = UnicastRemoteObject.exportObject(object, 0);
                registry.rebind(name, stub);
                if (remoteServer != null) {
                    remoteServer.registerRemoteObject(stub, name);
                }
            }


            LOGGER.logMessage(LogLevel.DEBUG, "结束注册本地对象:{}", name);
        } catch (RemoteException e) {
            LOGGER.errorMessage("注册本地对象:{}时发生异常:{}!", e, name, e.getMessage());
            registeredLocalObjectMap.remove(name);
            throw new RuntimeException(e);
        }
    }

    public void registerLocalObject(Remote object, Class type, String id)
            throws RemoteException {
        registerLocalObject(object, type.getName(), id);
    }

    public void registerLocalObject(Remote object, String type, String id)
            throws RemoteException {
        registerLocalObject(object, getKeyName(type, id));
    }

    public void registerLocalObject(Remote object, Class type)
            throws RemoteException {
        registerLocalObject(object, type.getName());
    }

    public void registerRemoteObject(Remote object, Class type, String id)
            throws RemoteException {
        registerRemoteObject(object, getKeyName(type.getName(), id));
    }

    public void registerRemoteObject(Remote object, String type, String id)
            throws RemoteException {
        registerRemoteObject(object, getKeyName(type, id));
    }

    public void registerRemoteObject(Remote object, String name)
            throws RemoteException {
        LOGGER.logMessage(LogLevel.DEBUG, "开始注册远程对象:{}", name);
        registeredRemoteObjectMap.put(name, object);
        LOGGER.logMessage(LogLevel.DEBUG, "注册远程对象:{}结束", name);
    }

    public void registerRemoteObject(Remote object, Class type)
            throws RemoteException {
        registerRemoteObject(object, type.getName());
    }

    public void unregisterObject(Remote object) throws RemoteException {
        LOGGER.logMessage(LogLevel.DEBUG, "开始注销对象object:{}", object);
        boolean flag = false;
        for (String name : registeredLocalObjectMap.keySet()) {
            Remote r = registeredLocalObjectMap.get(name);
            if (r.equals(object)) {
                unregisterLocalObject(name);
                flag = true;
                break;
            }
        }
        if (!flag) {
            for (String name : registeredRemoteObjectMap.keySet()) {
                Remote r = registeredRemoteObjectMap.get(name);
                if (r.equals(object)) {
                    unregisterRemoteObject(name);
                    flag = true;
                    break;
                }
            }
        }
        if (!flag) {
            LOGGER.logMessage(LogLevel.ERROR, "需要注销的对象object:{}不存在", object);
        }
        LOGGER.logMessage(LogLevel.DEBUG, "注销对象object:{}完成", object);
    }

    private void unregisterLocalObject(String name) throws RemoteException {
        try {
            LOGGER.logMessage(LogLevel.DEBUG, "开始注销本地对象:{}", name);
            registry.unbind(name);
            if (registeredLocalObjectMap.get(name) != null) {
                UnicastRemoteObject.unexportObject(
                        registeredLocalObjectMap.get(name), true);
            }
            registeredLocalObjectMap.remove(name);
            if (remoteServer != null) {
                remoteServer.unregisterObject(name);
            }
            LOGGER.logMessage(LogLevel.DEBUG, "注销本地对象:{}完成", name);
        } catch (Exception e) {
            LOGGER.errorMessage("注销对象:{}时发生异常:{}!", e, name, e.getMessage());
        }
    }

    private void unregisterRemoteObject(String name) throws RemoteException {
        LOGGER.logMessage(LogLevel.DEBUG, "开始注销远程对象:{}", name);
        registeredRemoteObjectMap.remove(name);
        LOGGER.logMessage(LogLevel.DEBUG, "注销远程对象:{}完成", name);
    }

    public void unregisterObject(String name) throws RemoteException {
        LOGGER.logMessage(LogLevel.DEBUG, "开始注销对象:{}", name);
        if (registeredLocalObjectMap.containsKey(name)) {
            unregisterLocalObject(name);
        } else if (registeredRemoteObjectMap.containsKey(name)) {
            unregisterRemoteObject(name);
        } else {
            LOGGER.logMessage(LogLevel.ERROR, "需要注销的对象name:{}不存在", name);
        }
        LOGGER.logMessage(LogLevel.DEBUG, "结束注销对象:{}", name);
    }

    public void unregisterObjectByType(Class type) throws RemoteException {
        LOGGER.logMessage(LogLevel.DEBUG, "开始注销对象type:{}", type.getName());
        unregisterLocalObjectByType(type);
        unregisterRemoteObjecttByType(type);
        LOGGER.logMessage(LogLevel.DEBUG, "注销对象type:{}完成", type.getName());
    }

    private void unregisterLocalObjectByType(Class type) throws RemoteException {
        String typeName = type.getName();
        for (String name : registeredLocalObjectMap.keySet()) {
            if (name.startsWith(typeName + "|")) { // 如果名称是以typeName打头
                unregisterLocalObject(name);
            } else {
                Object obj = registeredLocalObjectMap.get(name); // 如果名称不匹配再进行类型判断
                if (type.isAssignableFrom(obj.getClass())) {
                    unregisterLocalObject(name);
                }
            }
        }
    }

    private void unregisterRemoteObjecttByType(Class type)
            throws RemoteException {
        String typeName = type.getName();
        for (String name : registeredRemoteObjectMap.keySet()) {
            if (name.startsWith(typeName + "|")) { // 如果名称是以typeName打头
                unregisterRemoteObject(name);
            } else {
                Object obj = registeredRemoteObjectMap.get(name); // 如果名称不匹配再进行类型判断
                if (type.isInstance(obj)) {// type.isAssignableFrom(obj.getClass())
                    unregisterRemoteObject(name);
                }
            }

        }
    }

    public void unregisterObjectByType(String type) throws RemoteException {
        try {
            unregisterObjectByType(Class.forName(type));
        } catch (ClassNotFoundException e) {
            LOGGER.errorMessage("注销类型为:{}的对象时发生异常:{}!", e, type, e.getMessage());
        }

    }

    public void unregisterObject(String type, String id) throws RemoteException {
        unregisterObject(getKeyName(type, id));
    }

    public void unregisterObject(Class type, String id) throws RemoteException {
        unregisterObject(getKeyName(type.getName(), id));
    }

    public  T getObject(String name) throws RemoteException {

        if (registeredLocalObjectMap.containsKey(name)) {
            return (T) registeredLocalObjectMap.get(name);
        }
        if (registeredRemoteObjectMap.containsKey(name)) {
            return (T) registeredRemoteObjectMap.get(name);
        }
        if (remoteServer != null) {
            return (T) remoteServer.getObject(name);
        }
        return null;
    }

    public  T getObject(Class type) throws RemoteException {
        for (String sName : registeredRemoteObjectMap.keySet()) {
            try {
                Remote object = getObject(sName);
                if (type.isInstance(object)) {
                    return (T) object;
                }
            } catch (RemoteException e) {
                LOGGER.errorMessage("获取对象Name:{}时出现异常", e, sName);
            }
        }
        for (String sName : registeredLocalObjectMap.keySet()) {
            try {
                Remote object = getObject(sName);
                if (type.isInstance(object)) {
                    return (T) object;
                }
            } catch (RemoteException e) {
                LOGGER.errorMessage("获取对象Name:{}时出现异常", e, sName);
            }
        }
        if (remoteServer != null) {
            return remoteServer.getObject(type);
        }
        return null;
    }

    private  void getObjectListInstanceOf(Class type, List result,
                                             Map map) throws RemoteException {
        for (String sName : map.keySet()) {
            try {
                Remote object = getObject(sName);
                if (type.isInstance(object) && !result.contains(object)) {
                    result.add((T) object);
                }
            } catch (RemoteException e) {
                LOGGER.errorMessage("获取对象Name:{}时出现异常", e, sName);
            }
        }
    }

    public  List getObjectList(Class type) throws RemoteException {
        return getObjectList(type.getName());
    }

    private  void getObjectList(String typeName, List result,
                                   Map map) throws RemoteException {
        for (String sName : map.keySet()) {
            Object o = map.get(sName);
            if (result.contains(o)) {
                continue;
            }
            if (sName.startsWith(typeName + "|")) {
                result.add((T) o);
            } else if (o.getClass().toString().equals(typeName)) {
                result.add((T) o);
            }
        }
    }

    public  List getObjectList(String typeName) throws RemoteException {
        List result = new ArrayList();
        getObjectList(typeName, result, registeredLocalObjectMap);
        getObjectList(typeName, result, registeredRemoteObjectMap);
        if (remoteServer != null) {
            List list = remoteServer.getObjectList(typeName);
            for (Object t : list) {
                if (!result.contains(t)) {
                    result.add((T) t);
                }
            }
        }
        return result;
    }

    public  List getRemoteObjectListInstanceOf(Class type)
            throws RemoteException {
        List result = new ArrayList();
        getObjectListInstanceOf(type, result, registeredLocalObjectMap);
        getObjectListInstanceOf(type, result, registeredRemoteObjectMap);
        if (remoteServer != null) {
            List list = remoteServer.getRemoteObjectListInstanceOf(type);
            for (T t : list) {
                if (!result.contains(t)) {
                    result.add(t);
                }
            }
        }
        return result;
    }

    public void unexportObjects() throws RemoteException {
        List names = new ArrayList();
        for (String name : registeredLocalObjectMap.keySet()) {
            names.add(name);
        }
        for (String name : names) {
            try {
                unregisterLocalObject(name);
            } catch (Exception e) {
                LOGGER.errorMessage("注销对象name:{}时失败", e, name);
            }
        }
        names.clear();

        for (String name : registeredRemoteObjectMap.keySet()) {
            names.add(name);
        }
        for (String name : names) {
            try {
                unregisterRemoteObject(name);
            } catch (Exception e) {
                LOGGER.errorMessage("注销对象name:{}时失败", e, name);
            }
        }
    }

    private String getKeyName(String name, String id) throws RemoteException {
        return RmiUtil.getName(name, id);
    }

    class HeartThread extends Thread implements Serializable {
        private static final int MILLISECOND_PER_SECOND = 1000;
        private volatile boolean stop = false;
        private int breathInterval = 20;// 单位秒

        public void setStop(boolean stop) {
            this.stop = stop;
        }

        public void run() {
            while (!stop) {

                try {
                    sleep(breathInterval * MILLISECOND_PER_SECOND);
                } catch (InterruptedException e) {
                    continue;
                }
                LOGGER.logMessage(LogLevel.DEBUG, "开始检测远端服务器的可用性");
                try {
                    remoteRegistry.list();
                    LOGGER.logMessage(LogLevel.DEBUG, "远端服务器正常");
                } catch (Exception e) {
                    LOGGER.logMessage(LogLevel.DEBUG, "远端服务器不可用,开始尝试重新获取");
                    try {
                        getRemoteRegistry();
                        LOGGER.logMessage(LogLevel.DEBUG, "远端服务器尝试重新获取成功");
                    } catch (Exception e2) {
                        LOGGER.logMessage(LogLevel.DEBUG, "远端服务器尝试重新获取失败");
                        continue;
                    }

                }
                if (!checkRemoteHasThis()) {
                    LOGGER.logMessage(LogLevel.DEBUG, "远端服务器上不存在本地服务器信息");
                    reReg();
                    List list = triggers
                            .get(ConnectTrigger.REREG);
                    for (ConnectTrigger trigger : list) {
                        trigger.deal();
                    }

                }
                LOGGER.logMessage(LogLevel.DEBUG, "检测远端服务器的可用性完成");
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy