mirror of
https://gitee.com/willfree/CUTV_FileSystemV2.git
synced 2026-06-03 08:16:51 +08:00
775 lines
33 KiB
Java
775 lines
33 KiB
Java
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<Long, Integer> 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();
|
|
}
|
|
|
|
}
|