zoukankan      html  css  js  c++  java
  • dubbo远程方法调用的基本原理

    1 dubbo是远程服务调用rpc框架

    2 dubbo缺省协议采用单一长连接和NIO通讯

    1client端生成一个唯一的id,封装方法调用信息obj(接口名,方法名,参数,处理结果的回调对象),在全局的ConcurrentHashMap中保存put(id,obj), 将id和obj发送到server端,当前线程使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。

    2server端接收到请求并处理后,返回给client端处理结果,client从中取到ID,再从前面的ConcurrentHashMap里面get(ID),从而找到callback,将方法调用结果设置到callback对象里 ,使用synchronized获取回调对象callback的锁(因为前面调用过wait(),那个线程已释放callback的锁了),再notifyAll(),唤醒前面处于等待状态的线程继续执行

     

     

     

     

    参考:https://blog.csdn.net/paul_wei2008/article/details/19355681

     

    在实际项目有类似的需求,不过没有用锁机制,线程等待,直接使用sleep方法了

    package com.moreas.r1;
    
    public interface Event {
    	public void handlerEvent(Object params);
    }
    

      

     

    package com.moreas.r1;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class RemoteService implements Event {
    
    	private int monitor_result = 0;
    
    	public Object remoteLocate(String deviceID) {
    
    		Map<String, Object> returnMap = new HashMap<>();
    		returnMap.put("code", 1);
    
    		@SuppressWarnings("unchecked")
    		Map<String, Object> deviceMap = (Map<String, Object>) ServerManager.application.get(deviceID);
    
    		// 生成指令
    		String msgID = Utils.createMsgID();
    		OrderEntity order = new OrderEntity();
    		order.setMsgID(msgID);
    		order.setCmd("Monitor");
    		order.setDeviceID(deviceID);
    
    		deviceMap.put("MsgId", msgID);
    		ServerManager.application.put(deviceID, deviceMap);
    
    		// 将自己添加到回调的map中
    		LocateService.addHandlerEvent(deviceID + "_Monitor", this);
    
    		// 使用socket将指令order发送出去
    
    		// 等待
    		try {
    
    			int cnt = 0;
    			while ((monitor_result == 0) && cnt < 280) {
    				Thread.sleep(100);
    				cnt++;
    			}
    
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		if (monitor_result != 0) { // 通过handlerEvent方法将处理结果设置到monitor_result中
    			returnMap.put("code", 2);
    		} else {
    			System.out.println("请求超时了");
    			returnMap.put("code", 2);
    		}
    
    		LocateService.removeHandlerEvent(deviceID + "_Monitor");
    		return returnMap;
    
    	}
    
    	@Override
    	public void handlerEvent(Object params) {
    		Map map = (Map) params;
    		if (((String) map.get("result")).equals(123)) {
    			monitor_result = 11;
    		}
    	}
    
    }
    

      

    package com.moreas.r1;
    
    import java.util.HashMap;
    
    public class LocateService extends CallBack {
    
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public void handlerUploadLctDataByApp(OrderEntity receiveOrder, String deviceID) {
    		// 通过receiveOrder取得参数,调用本地方法获取结果result
    		int resultData = 1;
    
    		if (resultData == 1) {
    
    			Event event = getEvent(deviceID + "_Monitor");
    			if (event != null) {
    				HashMap map = new HashMap<>();
    				map.put("locResult", "123");
    				event.handlerEvent(map);
    			}
    		}
    	}
    
    }
    

      

    package com.moreas.r1;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class CallBack {
    
    	private static Map<String, Event> eventList = new HashMap<>();
    
    	public static void addHandlerEvent(String key, Event eventClass) {
    
    		if (eventList.containsKey(key)) {
    			return;
    		}
    
    		synchronized (eventList) {
    			eventList.put(key, eventClass);
    		}
    	}
    
    	public static void removeHandlerEvent(String key) {
    
    		if (!eventList.containsKey(key)) {
    			return;
    		}
    
    		synchronized (eventList) {
    			eventList.remove(key);
    		}
    	}
    
    	public static void clearHandlerEvent() {
    
    		synchronized (eventList) {
    			eventList.clear();
    		}
    	}
    
    	public static boolean containsKey(String key) {
    
    		return eventList.containsKey(key);
    	}
    
    	public static Event getEvent(String key) {
    
    		if (!containsKey(key))
    			return null;
    
    		return eventList.get(key);
    	}
    
    }
    

      

    package com.moreas.r1;
    
    import java.util.Map;
    
    public class ReceiveData {
    	
    	
    
    	//order是接受到的指令,接受到指令后,进行处理
    	@SuppressWarnings({ "unused", "unchecked" })
    	private void handler(OrderEntity order) {
    		
    		if(order.getCmd().equals("Monitor")){
    			//获取application中的MsgId
    			String deviceID = order.getDeviceID();
    			Map<String, Object> deviceMap = (Map<String, Object>)ServerManager.application.get(deviceID);
    			String msgID = (String)deviceMap.get("MsgId");
    			//order中的MsgId
    			if(msgID.equals(order.getMsgID())) {
    				
    				new LocateService().handlerUploadLctDataByApp(order, deviceID);
    				
    				deviceMap.remove("MsgId");
    				ServerManager.application.put(deviceID,deviceMap);
    			}
    			
    		}
    		
    		
    	}
    }
    

      

    package com.moreas.r1;
    
    public class OrderEntity {
    
    	private String msgID; // 消息ID
    
    	private String cmd;
    
    	private String deviceID;
    
    	public String getDeviceID() {
    		return deviceID;
    	}
    
    	public void setDeviceID(String deviceID) {
    		this.deviceID = deviceID;
    	}
    
    	public String getCmd() {
    		return cmd;
    	}
    
    	public void setCmd(String cmd) {
    		this.cmd = cmd;
    	}
    
    	public String getMsgID() {
    		return msgID;
    	}
    
    	public void setMsgID(String msgID) {
    		this.msgID = msgID;
    	}
    
    	public String getMsg() {
    		return "123";
    	};
    }
    

      

    package com.moreas.r1;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class ServerManager {
    
    	private static final String flag = "ServerManger";
    
    	public static Map<String, Object> application = new HashMap<String, Object>();
    
    }
    

      

    package com.moreas.r1;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Random;
    
    public class Utils {
    
    	public static String createMsgID() {
    
    		Random random = new Random();
    		int nonce = random.nextInt(1000);
    		String nonceStr = "" + nonce;
    		if (nonce < 100) {
    			nonceStr = "0" + nonceStr;
    			if (nonce < 10) {
    				nonceStr = "0" + nonceStr;
    			}
    		}
    
    		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    		String currTime = df.format(new Date());
    
    		return currTime + "-" + nonceStr;
    	}
    }
    

      

     

  • 相关阅读:
    VMware6.0-vCenter的安装准备及安装
    VeeamBackup9.5安装与配置
    VeeamOne(Free Edition 9.5 )-安装与配置
    UIDatePicker
    UIImagePicker照片选择器
    UIImageView
    UILabel
    UIScrollView 期本使用方法
    UISegment
    UISlide
  • 原文地址:https://www.cnblogs.com/moris5013/p/10064496.html
Copyright © 2011-2022 走看看