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;
}
}
