package cn.minoa.dataRequestInterface; // 与服务器进行数据交互 import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import cn.minoa.model.SingleNotice; import cn.minoa.util.Aes; import cn.minoa.util.KeyStorageUtil; import net.named_data.jndn.*; import net.named_data.jndn.security.pib.Pib; import net.named_data.jndn.security.pib.PibImpl; import net.named_data.jndn.security.tpm.Tpm; import net.named_data.jndn.security.tpm.TpmBackEnd; import net.named_data.jndn.security.v2.CertificateV2; import org.json.JSONException; import org.json.JSONObject; import cn.minoa.MainApp; import cn.minoa.model.SingleMessage; import net.named_data.jndn.encoding.EncodingException; import net.named_data.jndn.security.KeyChain; import net.named_data.jndn.security.SecurityException; import net.named_data.jndn.security.pib.PibIdentity; import net.named_data.jndn.security.pib.PibImpl.Error; import net.named_data.jndn.security.pib.PibSqlite3; import net.named_data.jndn.security.tpm.TpmBackEndMemory; import net.named_data.jndn.util.Blob; public class MinoaDataAPI { public static String keyChainNameString = "/default"; public static String minoaServerIpString; public static Integer minoaServerPortInteger; public static String globalPrefixString; // private String pidDbPathString; // 同一兴趣包超时或丢包次数达到上限时的错误信息 public static String timeoutError = "timeout times reaches the upper limit."; // 由于连接问题(多次超时/丢包),返回给主线程的错误码 public static Integer timeoutCodeInteger = 333; // 同一兴趣包超时或丢包次数达到上限时的错误信息 public static String nackError = "receive nack."; // 由于连接问题(多次超时/丢包),返回给主线程的错误码 public static Integer nackCodeInteger = 334; // 除文件上下传外的应答codeInteger非200/201时的报错信息 // 判断是否是200/201,不会导致界面卡死,超时才会 public static String wrongAnswerError = "answer codeInteger is not 200/201."; // public static KeyChain keyChain; public static Face face; public volatile DataCacheQueue dataCacheQueue; private MainApp mainApp; // 标志连接是否正常 private boolean isConnected; //发送的数据是否发送成功,key:第几个数据片,从0开始,value:该数据片超时次数 private Map timeOutNums = new ConcurrentHashMap<>(); // 超时重传上限数值,某个兴趣包的重传次数超过此数值,则放弃重传,直接返回false private Integer timeoutCeil = 10; public MinoaDataAPI(MainApp mainApp) { // TODO Auto-generated constructor stub minoaServerIpString = mainApp.minoaServerIpString; minoaServerPortInteger = mainApp.minoaServerPortInteger; globalPrefixString = mainApp.globalPrefixString; isConnected = false; this.dataCacheQueue = new DataCacheQueue(); this.mainApp = mainApp; // pidDbPathString=mainApp.getClientPath()+ File.separator+"ndn"; // System.out.println("pidDbPathString: "+pidDbPathString); runFace(minoaServerIpString, minoaServerPortInteger); // 首先按照"/default"初始化KeyChain try { KeyManager.INSTANCE.initKeyChain(keyChainNameString); } catch (Pib.Error | PibImpl.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) { error.printStackTrace(); } // 从本地初始化keyName String keyString=KeyStorageUtil.getKeyName(); try { // 如果本地keyName指向的证书确实在keyChain中,就将该证书取出 if((keyString!=null)&&(KeyManager.INSTANCE.isInKeyChain(keyString))){ keyChainNameString=keyString; System.out.println("keyChainNameString: "+keyChainNameString); // 再次按照本地证书前缀初始化KeyChain try { KeyManager.INSTANCE.initKeyChain(keyChainNameString); } catch (Pib.Error | Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) { error.printStackTrace(); } } } catch (Pib.Error | PibImpl.Error | Tpm.Error | TpmBackEnd.Error | CertificateV2.Error | KeyChain.Error error) { error.printStackTrace(); } // try { // // 密钥“黑盒” // PibSqlite3 pibSqlite3 = new PibSqlite3(pidDbPathString); // TpmBackEndMemory tpmBackEndMemory = new TpmBackEndMemory(); // keyChain = new KeyChain(pibSqlite3, tpmBackEndMemory); // PibIdentity identity = keyChain.getPib().getIdentity(new Name(keyChainNameString)); // keyChain.setDefaultIdentity(identity); // // System.out.println(keyChain.getDefaultCertificateName().toUri()); // } catch (Exception e) { // // TODO: handle exception // System.out.println("exception: " + e.getMessage()); // } } /** * 判断某个key对应的兴趣包的超时次数是否超过阈值 * * @return */ private boolean isInterestTimeOut(Long timeoutMapKey) { if (timeOutNums.get(timeoutMapKey) > timeoutCeil) { return true; } return false; } // 开辟线程运行face public boolean runFace(String ipString, Integer portInteger) { if (isConnected) { return true; } this.face = new Face(ipString, portInteger); isConnected = true; Thread thread = new Thread(new Runnable() { @Override public void run() { // System.out.println("face is trying to link..."); // TODO Auto-generated method stub try { while (true) { face.processEvents(); // 线程暂时休眠 Thread.sleep(5); } } catch (InterruptedException | EncodingException | IOException e) { // TODO Auto-generated catch block // e.printStackTrace(); System.out.println(e.getMessage()); isConnected = false; } } }); thread.start(); return isConnected; } public boolean runFace(String ipString) { return this.runFace(ipString, minoaServerPortInteger); } public boolean runFace() { return this.runFace(minoaServerIpString, minoaServerPortInteger); } // 开辟线程监听新消息/新通知/新审批:作为心跳包存在,五秒一次 public void bindNews() { Thread thread = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (true) { // 监听是否有新消息等,有,则将其加载到数据内存 bindNewsProdution(); // 线程暂时休眠 try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); thread.start(); } // 监听函数:作为心跳包存在,不进行任何处理 public void bindNewsProdution() { // 发送数据请求 Long seqLong = mainApp.getNewDataReqId(); OrderInfo orderInfo = new OrderInfo(); orderInfo.setSeq(seqLong); orderInfo.setJsonString(getGetNewsJson()); mainApp.minoaDataAPI.executeOrder("/getNews", orderInfo); // 获取回复消息 ResponseData responseData = mainApp.minoaDataAPI.dataCacheQueue.getResponseDataBySeq(seqLong); // System.out.println("getNews-responseData: "+responseData.getResponseJsonDataString()); JSONObject jsonObject = responseData.praseRequestData(); Integer codeInteger = null; try { codeInteger = jsonObject.getInt("code"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(jsonObject.toString()); // 如果需要查看登录状态且登录失效 if (mainApp.isNeedKnowLoginStatus&&(codeInteger == 407)) { // 登录失效 mainApp.isNeedKnowLoginStatus=false; mainApp.reLogin(); } // String dataString; // try { // dataString = jsonObject.getString("data"); // if (!dataString.equals("")) { //// System.out.println("getNews-responseData: "+responseData.getResponseJsonDataString()); // JSONArray dataJsonArray = new JSONArray(dataString); // String newsCacheString; // JSONObject newsCacheJsonObject; // Integer typeCodeInteger; // String contentString; // // 遍历每个新消息或者通知或者审批 将其更新到前端内存数据中 // for (int i = 0; i < dataJsonArray.length(); i++) { // newsCacheString = dataJsonArray.getString(i); // newsCacheJsonObject = new JSONObject(newsCacheString); // typeCodeInteger = newsCacheJsonObject.getInt("typeCode"); // contentString = newsCacheJsonObject.getString("content"); // if (typeCodeInteger == 0) { // // 处理新消息 // handleNewSingleMessage(contentString); // } else if (typeCodeInteger == 1) { // // 处理新通知 //// System.out.println("getNews-responseData: "+responseData.getResponseJsonDataString()); // handleNewSingleNotice(contentString); // } else if (typeCodeInteger == 2) { // // 处理新审批[报销审批、邮件] // System.out.println("getNews-responseData: "+responseData.getResponseJsonDataString()); // handleNewSingleApproval(contentString); // } // } // }else{ //// System.out.println("getNews-responseData: "+responseData.getResponseJsonDataString()); // } // } catch (JSONException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } } //接收到一个新的审批[邮件/报销审批等,除掉通知] private void handleNewSingleApproval(String singleApprovalString) { try { JSONObject singleApprovalJsonObject = new JSONObject(singleApprovalString); //拿到审批类型 Integer typeCodeInteger = singleApprovalJsonObject.getInt("typeCode"); if (typeCodeInteger == 2) { System.out.println("接收到一条新的报销审批【我是审核人】"); mainApp.handleGetNewReimToSelf(); } else if (typeCodeInteger == 3) { System.out.println("接收到一条新的邮件【我是接收方】"); mainApp.handleGetNewEmailToSelf(); } } catch (JSONException e) { e.printStackTrace(); } } //接收到一个新的通知 private void handleNewSingleNotice(String singleNoticeString) { String singleNoticeCacheString = singleNoticeString; JSONObject singleNoticeCacheJsonObject; Integer noticeIdInteger; String usernameCacheString; String titleCacheString; String contentCacheString; String starttimeCacheString; String endtimeCacheString; String attachementCacheString; try { singleNoticeCacheJsonObject = new JSONObject(singleNoticeCacheString); //拿到通知ID noticeIdInteger = singleNoticeCacheJsonObject.getInt("approvalId"); // 拿到新闻发布人 usernameCacheString = singleNoticeCacheJsonObject.getString("proposer"); // 拿到content // JSONObject detailJsonObject = singleNoticeCacheJsonObject.getJSONObject("detail"); String detailString = singleNoticeCacheJsonObject.getString("detail"); System.out.println("通知详细: " + detailString); JSONObject detailJsonObject = new JSONObject(detailString); contentCacheString = detailJsonObject.getString("content"); // 拿到title titleCacheString = detailJsonObject.getString("title"); // 拿到starttime、endtime starttimeCacheString = detailJsonObject.getString("startTime"); endtimeCacheString = detailJsonObject.getString("endTime"); // 拿到attachment attachementCacheString = detailJsonObject.getString("attachment"); // System.out.println("user-"+i+": "+usernameCacheString); // 新建一个notice SingleNotice singleNotice = new SingleNotice(); singleNotice.setNoticeId(noticeIdInteger); singleNotice.setContent(contentCacheString); singleNotice.setUsername(usernameCacheString); singleNotice.setTitle(titleCacheString); singleNotice.setStarttime(starttimeCacheString); singleNotice.setEndtime(endtimeCacheString); singleNotice.setAttachment(attachementCacheString); //判断该通知是否已经渲染到前端 boolean flagInNoticeList = isInNoticeList(singleNotice.getNoticeId()); if (!flagInNoticeList) { mainApp.handleGetNewNotice(singleNotice); System.out.println("MinoaDataAPI-handleGetNewMessage success: " + singleNoticeString); } } catch (JSONException e) { e.printStackTrace(); } } //判断某个通知(的ID)是否已经在前端数据中存在 boolean isInNoticeList(Integer noticeId) { boolean flag = false; for (int i = 0; i < mainApp.noticeList.size(); i++) { if (mainApp.noticeList.get(i).getNoticeId() == noticeId) { flag = true; break; } } return flag; } // 获取是否有新的[消息/通知/审批]产生的json字符串 private String getGetNewsJson() { JSONObject jsonObject = new JSONObject(); String commandString = "/getNews"; String userNameString = mainApp.loginer.getUserName(); String uuidString = mainApp.loginer.getUuid(); try { jsonObject.put("command", commandString); jsonObject.put("username", userNameString); jsonObject.put("uuid", uuidString); } catch (Exception e) { // TODO: handle exception System.out.println("exception: " + e.getMessage()); } return jsonObject.toString(); } // 处理一条接收到的新聊天消息 private void handleNewSingleMessage(String singleMessageString) { try { JSONObject singleMessageJsonObject = new JSONObject(singleMessageString); String fromString; JSONObject fromJsonObject; String fromNameString; Integer idInteger; String msgString; Long timeLong; // 解析发送方姓名 fromString = singleMessageJsonObject.getString("from"); fromJsonObject = new JSONObject(fromString); fromNameString = fromJsonObject.getString("username"); // 解析id idInteger = singleMessageJsonObject.getInt("id"); // 解析内容 msgString = singleMessageJsonObject.getString("msg"); // 解析时间 timeLong = singleMessageJsonObject.getLong("time"); // 构建一条消息对象 SingleMessage singleMessage = new SingleMessage(); singleMessage.setFromName(fromNameString); singleMessage.setMsg(msgString); singleMessage.setTime(timeLong); singleMessage.setToName(mainApp.loginer.getUserName()); singleMessage.setMsgId(idInteger); // 将这条新消息交给mainApp处理 mainApp.handleGetNewMessage(singleMessage); System.out.println("MinoaDataAPI-handleGetNewMessage success: " + singleMessageString); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 根据命令前缀获取相应的请求字符串【JSON】 public static String getRequestStr(String orderPrefix, OrderInfo orderInfo) { String requestStr; switch (orderPrefix) { case "/register": requestStr = orderInfo.getJsonString(); break; case "/login": requestStr = orderInfo.getJsonString(); break; case "/getUsers": requestStr = orderInfo.getJsonString(); break; case "/sendRTMsg": requestStr = orderInfo.getJsonString(); break; case "/getRTMsg": requestStr = orderInfo.getJsonString(); break; case "/getRTMsgLog": requestStr = orderInfo.getJsonString(); break; case "/getInform": requestStr = orderInfo.getJsonString(); break; case "/hasNews": requestStr = orderInfo.getJsonString(); break; case "/getNews": requestStr = orderInfo.getJsonString(); break; case "/fileAction": requestStr = orderInfo.getJsonString(); break; case "/fileInfo": requestStr = orderInfo.getJsonString(); break; case "/fileShareInfo": requestStr = orderInfo.getJsonString(); break; case "/downloadFile": requestStr = orderInfo.getJsonString(); break; case "/downloadShareFile": requestStr = orderInfo.getJsonString(); break; case "/uploadFile": requestStr = orderInfo.getJsonString(); break; case "/sendApproval": requestStr = orderInfo.getJsonString(); break; case "/getApproval": requestStr = orderInfo.getJsonString(); break; case "/getDataSlice": requestStr = orderInfo.getJsonString(); break; case "/dealApproval": requestStr = orderInfo.getJsonString(); break; case "/ecos_begin": requestStr = orderInfo.getJsonString(); break; case "/ecos_end": requestStr = orderInfo.getJsonString(); break; default: requestStr = "*wrong command string*"; break; } return requestStr; } // 执行数据请求语句 public boolean executeOrder(String orderPrefix, OrderInfo orderInfo) { // 获取json格式的数据请求字符串 String requestStr = getRequestStr(orderPrefix, orderInfo); System.out.println("requestStr: "+requestStr); // 命令前缀格式不对的情况下返回false if (requestStr.equals("*wrong command string*")) { System.out.println(requestStr); return false; } // AES加密 byte[] requestByte=null; if(orderPrefix.equals("/register")||orderPrefix.equals("/login")){ }else{ try { requestByte= Aes.newEncrypt(requestStr,Aes.getDefaultKey()); // requestStr=Aes.Encrypt(requestStr); } catch (Exception e) { System.out.println("AES加密错误:"+e.getMessage()); } } // 发送数据兴趣包 Name name = new Name(globalPrefixString + orderPrefix+"/"+orderInfo.getSeq() +"/" +mainApp.loginer.getUserName()+"/"+(System.currentTimeMillis()/1000+MainApp.timeStampBias)); Interest interest = new Interest(name); interest.setMustBeFresh(true); // if(orderPrefix.equals("/login")){ if(orderPrefix.equals("/register")||orderPrefix.equals("/login")){ Base64.Decoder base64Decoder = Base64.getMimeDecoder() ; interest.setApplicationParameters(new Blob(base64Decoder.decode(requestStr))); }else{ interest.setApplicationParameters(new Blob(requestByte)); } interest.setInterestLifetimeMilliseconds(2000); try { // keyChain.sign(interest); // 使用KeyManager管理兴趣包签名 KeyManager.INSTANCE.getKeyChain().sign(interest); this.expressTheInterest(orderPrefix, interest, orderInfo.getSeq()); return true; } catch (Exception e) { System.out.println("exception: " + e.getMessage()); return false; } } // 提供特殊接口,执行数据请求语句:为ECOS信号服务 public boolean executeOrder(String orderPrefix,Interest interest,Long seq) { try { this.expressTheInterest(orderPrefix, interest, seq); return true; } catch (Exception e) { System.out.println("exception: " + e.getMessage()); return false; } } // 提供特殊接口,执行时间戳同步语句 public boolean executeOrder(String orderPrefix,OrderInfo orderInfo,boolean isTimeSync) { // 发送数据兴趣包 Name name = new Name(globalPrefixString + orderPrefix+"/"+orderInfo.getSeq()); Interest interest = new Interest(name); interest.setMustBeFresh(true); System.out.println("time sync: "+orderInfo.getJsonString()); interest.setApplicationParameters(new Blob(orderInfo.getJsonString())); interest.setInterestLifetimeMilliseconds(2000); try { // keyChain.sign(interest); // 使用KeyManager管理兴趣包签名 KeyManager.INSTANCE.getKeyChain().sign(interest); this.expressTheInterest(orderPrefix, interest, orderInfo.getSeq()); return true; } catch (Exception e) { System.out.println("exception: " + e.getMessage()); return false; } } private void expressTheInterest(String orderPrefix, Interest interest, Long dataReqId) { ResponseData responseData = new ResponseData(); responseData.setPrefix(orderPrefix); HandleInterestTimeOutAndNack handleInterestTimeOutAndNack = new HandleInterestTimeOutAndNack(orderPrefix, interest, dataReqId); try { // 使用匿名内部类,发送数据请求兴趣包 if (orderPrefix.equals("/getDataSlice")) { //接收数据块 face.expressInterest(interest, new OnData() { @Override public void onData(Interest interest, Data data) { // int contentSize = data.getContent().size(); // System.out.println("该大数据传输的数据块分片长度为:" + contentSize); // byte[] content = new byte[contentSize]; // for (int i = 0; i < contentSize; i++) { // content[i] = data.getContent().buf().get(i); // System.out.print(i + ": " + content[i] + " "); // } // System.out.println("notice content: " + content); byte[] dataBuf = new byte[data.getContent().size()] ; data.getContent().buf().get(dataBuf,0,data.getContent().size()) ; // Base64.Encoder base64Encoder = Base64.getMimeEncoder(); // String dataContentBase64 = base64Encoder.encodeToString(dataBuf); String plainText = null ; try { plainText = Aes.newDecrypt(dataBuf,Aes.getDefaultKey()) ; } catch (Exception e) { e.printStackTrace(); } responseData.setFileSlice(plainText.getBytes(StandardCharsets.UTF_8)); dataCacheQueue.setResponseData(dataReqId, responseData); // 重置其超时次数记录 if (timeOutNums.containsKey(dataReqId)) { timeOutNums.remove(dataReqId); } } }, handleInterestTimeOutAndNack, handleInterestTimeOutAndNack); } else if(orderPrefix.equals("/timeSync")||orderPrefix.equals("/register")){ face.expressInterest(interest, new OnData() { @Override public void onData(Interest interest, Data data) { byte[] dataBuf = new byte[data.getContent().size()]; data.getContent().buf().get(dataBuf, 0, data.getContent().size()); responseData.setResponseData(data.getContent().toString()); dataCacheQueue.setResponseData(dataReqId, responseData); // 重置其超时次数记录 if (timeOutNums.containsKey(dataReqId)) { timeOutNums.remove(dataReqId); } } },handleInterestTimeOutAndNack, handleInterestTimeOutAndNack); }else { face.expressInterest(interest, new OnData() { @Override public void onData(Interest interest, Data data) { // System.out.println("on data success"); // TODO Auto-generated method stub // System.out.println("ondata interest: "+interest.getName()); // System.out.println("ondata data: "+data.getContent().toString()); byte[] dataBuf = new byte[data.getContent().size()] ; data.getContent().buf().get(dataBuf,0,data.getContent().size()) ; // Base64.Encoder base64Encoder = Base64.getMimeEncoder(); // String dataContentBase64 = base64Encoder.encodeToString(dataBuf); String plainText = null ; try { plainText = Aes.newDecrypt(dataBuf,Aes.getDefaultKey()) ; } catch (Exception e) { e.printStackTrace(); } responseData.setResponseData(plainText); dataCacheQueue.setResponseData(dataReqId, responseData); // 重置其超时次数记录 if (timeOutNums.containsKey(dataReqId)) { timeOutNums.remove(dataReqId); } } }, handleInterestTimeOutAndNack, handleInterestTimeOutAndNack); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 写头像 // public Integer writeHeadPhotoIntoLocalFile(String filenameString, // Integer sliceNo,Integer sliceSize,byte[] bytes) { // String pathString=mainApp.fileLocalPath; // return writeIntoLocalFile(pathString, filenameString, sliceNo, sliceSize, bytes); // } // 根据包含路径的文件名获取纯文件名[linux下] public static String getPureFileName(String pathfilename) { // 标记最后一个/的下标 int indexLeft = -1; for (int i = 0; i < pathfilename.length(); i++) { if (pathfilename.charAt(i) == '/') { indexLeft = i; } } if (indexLeft == -1) { System.out.println("pure name[linux]: " + pathfilename); return pathfilename; } else { System.out.println("pure name[linux]: " + pathfilename.substring(indexLeft + 1, pathfilename.length())); return pathfilename.substring(indexLeft + 1, pathfilename.length()); } } // 根据包含路径的文件名获取纯文件名[windows本地] public static String getPureFileNameFromWindows(String pathfilename) { // 标记最后一个/的下标 int indexLeft = -1; for (int i = 0; i < pathfilename.length(); i++) { if (pathfilename.charAt(i) == '\\') { indexLeft = i; } } if (indexLeft == -1) { System.out.println("pure name[windows]: " + pathfilename); return pathfilename; } else { System.out.println("pure name[windows]: " + pathfilename.substring(indexLeft + 1, pathfilename.length())); return pathfilename.substring(indexLeft + 1, pathfilename.length()); } } // // 向指定本地文件写入指定数据分片=》被ondata调用 // public Integer writeIntoLocalFile(String pathString,String filenameString, // Integer sliceNo,Integer sliceSize,byte[] bytes) { // try { // @SuppressWarnings("resource") // RandomAccessFile randomAccessFile=new RandomAccessFile(pathString+filenameString, "rw"); // int contentSize= // randomAccessFile.write(bytes,sliceNo*sliceSize,bytes.length); // return 0; // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // return 1; // } // } // 关闭数据连接 public void closeDataConn() { this.face.shutdown(); } // 解决处理兴趣包超时之后的重传问题[除上传下载外的兴趣包] public class HandleInterestTimeOutAndNack implements OnTimeout, OnNetworkNack { // 命令前缀 private String orderPrefix; // 兴趣包 private Interest interest; // 请求序列号 private Long dataReqId; // 标记是否拿到网络回复(数据信息/超时信息):测试使用 public boolean isFinished = false; public HandleInterestTimeOutAndNack(String orderPrefix, Interest interest, Long dataReqId) { this.orderPrefix = orderPrefix; this.interest = interest; this.interest.setInterestLifetimeMilliseconds(2000); this.dataReqId = dataReqId; } // 处理兴趣包超时 @Override public void onTimeout(Interest interest) { // 打印超时信息 System.out.println("########## Time out for interest " + interest.getName() + "###########"); // 记录此次丢包/超时 if (timeOutNums.containsKey(this.dataReqId)) { int value = timeOutNums.get(this.dataReqId) + 1; timeOutNums.put(this.dataReqId, value); } else { timeOutNums.put(this.dataReqId, 1); } // 根据是否多次超时,决定是否重传该兴趣包:暂时是全部重传 // 后期可以改作,超时次数超过阈值时候, // 自拟定一个指定值放入数据回复缓存区,前端控制类收到该值,就 // 判定网络极其拥塞,进行弹窗提示。 if (!isInterestTimeOut(this.dataReqId)) { // 超时次数没有超过阈值:重传该兴趣包 expressTheInterest(this.orderPrefix, this.interest, this.dataReqId); } else { // 超时次数超过阈值 System.out.println("该兴趣包的超时次数超过阈值:" + timeoutCeil + "!!!"); // 返回一个timeout信息放入datacache ResponseData responseData = new ResponseData(); responseData.setPrefix(this.orderPrefix); responseData.setResponseData(getWrongAnswerJson(timeoutCodeInteger, timeoutError)); dataCacheQueue.setResponseData(this.dataReqId, responseData); } // 打印重传信息 System.out.println("########## Resend the interest " + interest.getName() + "###########"); // 处理完成 isFinished = true; } // 处理收到一个Nack包 @Override public void onNetworkNack(Interest interest, NetworkNack networkNack) { // 打印超时信息 System.out.println("########## Nack for interest " + interest.getName() + ", Nack: " + networkNack.toString()); // 返回一个nack信息放入datacache ResponseData responseData = new ResponseData(); responseData.setPrefix(this.orderPrefix); responseData.setResponseData(getWrongAnswerJson(nackCodeInteger, nackError)); dataCacheQueue.setResponseData(this.dataReqId,responseData); isFinished = true; } } // 构造一个json,给前端返回一个可以进行JSON解析的错误信息 // 用以避免界面卡死 public static String getWrongAnswerJson(Integer wrongAnswerCode, String wrongAnswerString) { JSONObject jsonObject = new JSONObject(); Integer code = wrongAnswerCode; String errMsg = wrongAnswerString; String data = ""; try { jsonObject.put("code", code); jsonObject.put("errMsg", errMsg); jsonObject.put("data", data); } catch (Exception e) { // TODO: handle exception System.out.println("exception: " + e.getMessage()); } return jsonObject.toString(); } }