
org.tinygroup.rmi.impl.RmiServerImpl Maven / Gradle / Ivy
/**
* Copyright (c) 1997-2013, 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);
}
}
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, "检测远端服务器的可用性完成");
}
}
}
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);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy