多文件自平衡云传输(二)资源接收端篇
资源接收端从请求到接收的过程:
1.资源接收端启动时先与拥有资源的服务器(可以是APP服务器,也可以是拥有资源的服务器)进行短连接进行资源资本信息的获取。
2.根据获取的资源的信息中的资源的名称进行短连接资源注册中心,请求拥有对应资源的节点列表。
3.根据资源基本信息中的资源的多个文件的基本信息进行本地资源的查询,若本地拥有该资源(之前可能进行过请求保存到本地)则进行缺省部分资源文件的请求,若本地无该资源,则进行全部资源的全部文件的请求。
4.在请求的过程中,资源接收端根据资源分配策略进行分配请求的资源的多个文件,将每个文件分成长度相等的多个片段。
5.接收端进行采用负载均衡策略进行可发送资源节点的选取,选取合适发送的节点,根据节点的个数将多个文件片段分成与节点个数相同的片段组,将每一组分派给节点。
6.将分好的资源片段组通过短连接的方式进行链接发送给该组对应的节点。
7.接收端开启临时的长连接服务器,进行接收发送端的链接与资源片段的发送
8.直到接收完整,当发送端出现异常导致接收端无法接收完整的时候,接收端启用断点续传的功能,再次进行缺省部分资源的请求。直到接收完整接收端拥有该资源。可以选择接收端此时作为一个发送端进行资源的注册,随意。
资源接收
Consumer
此类功能也即消费者的功能
1.进行资源发送节点的获取
2.选择负载均衡的策略,进行节点的选择。
public class Consumer {
private static int PORT = 54200;
private static String IP = "127.0.0.1";
private rmiCilent rc;
private CilentProxy cp;
private int RegisterPort = PORT;
private String RegisterIp = IP;
private NetNode self;
//节点选择策略
private INodeSelect nodeSelect;
//资源分配策略
private IResourceSelect resourceSelect;
private String resourceName;
public Consumer() {
this.cp = new CilentProxy();
rc = new rmiCilent();
rc.setPort(RegisterPort);
rc.setId(RegisterIp);
cp.setRmicilent(rc);
defaultInit();
}
public List<NetNode> getServerNode(String resorceName){
//通过名称得到拥有资源的节点列表
//通过链接注册中心得到节点列表
this.resourceName = resorceName;
IRegister ir = this.cp.getProxy(IRegister.class);
return ir.getServerList(resorceName);
}
private void defaultInit() {
//采用默认节点选择和分配策略
nodeSelect = new NodeSelect();
resourceSelect = new ResourceSelect();
//这里可以采用配置文件的方式进行节点策略的设定
}
public INodeSelect getNodeSelect() {
return nodeSelect;
}
public IResourceSelect getResourceSelect() {
return resourceSelect;
}
/*
*与注册中心进行短连接时的异常处理
*/
class RequstNodeException implements ICilentException{
@Override
public void peerAbnormalDrop() {
getServerNode(resourceName);
}
}
}
ReceiveServer
接收端的入口类,与Consumer不同的是,Consumer不同之处在于,Consumer的主要功能是获取节点和节点的负载均衡的选择。
ReceiveServer给外部一个可以请求资源的方法,对外部而言不用关心内部的请求过程,只需要知道调用了该方法可以请求资源。
真正的资源请求过程由内部去完成,在这里ReceiveServer这个类中关键的作用请求一个资源的基本信息,剩下的工作交给了ReceiveDeal 和Consumer来做,ReceiveDeal 类中拥有Consumer作为成员。
public class ReceiveServer{
private rmiCilent serverRc;
private CilentProxy cp;
private boolean processBar;
private IRequstAction Ire;
private ICilentException Ice;
public ReceiveServer(int connectServerPort, String connectServerIp) {
serverRc = new rmiCilent();
serverRc.setPort(connectServerPort);
serverRc.setId(connectServerIp);
cp = new CilentProxy();
cp.setRmicilent(serverRc);
}
/*
*通过链接资源服务器进行资源基本信息的获取
*并创建ReceiveDeal对象进行真正的节点列表的获取和资源的分配
*/
public void requstResource(String ResourceName) {
//先链接服务器,然后得到对应的资源的基本的信息
//先通过服务器得到资源的一个基本的信息。
Iserver server = cp.getProxy(Iserver.class);
//根据服务器得到资源的基本的信息
ResourceInfo ri = server.getResourceInfo(ResourceName);
ResourceInfo temp = ri.getResoureFromXml();
if(temp == null) {
//表明没有该资源,用户第一次请求资源的时候需要设置本地的存储路径
//可以给外边进行路径的设置,
String localRoot = Ire.notfoundLocalResource();
ri.setRoot(localRoot);
ri.saveObject();
ri.getAllFiles(ri.getFileInfoMap());
//根据请求的资源的左右构造请求的条件
}else {
//TODO
//根据本地的已经存储的路径,判断该路径下的文件是否完整
//如果完整则不用请求
//此时应该根据本地的记录,判断是否进行获取。
return;
}
//创建一个线程立即返回,这样对于客户端来说请求资源可以快速的响应
new ThreadPool().Execute(new ReceiveDeal(ri, processBar));
}
/*
* 是否设置使用接收文件进度条
* 同样也可以进行设置进度条的格式,采用set方法进行设置,
* 我这里给出的是默认的进度条,进度条不是必选项。
*/
public void IFuseProcessBar(boolean choose) {
this.processBar = choose;
}
/*
*设置请求资源过程中的异常和问题
*例如 本地无对应资源表明第一次申请,则需要设置存储路径
*/
public void setRequstServerException(IRequstAction Ire) {
this.Ire = Ire;
}
/*
*设置连接服务器的异常
*/
public void setConnectServerException(ICilentException Ice){
this.Ice = Ice;
}
}
ReceiveDeal
此类的作用就是进行需要请求资源的分配和合适节点的选择(节点列表的获取,资源的分片和节点的选择由Consumer来完成),ReceiveDeal主要进行将分片资源根据节点的个数分组,然后分配给相应个数的节点,与其节点进行短连接告知节点应该发送的片段,并开启线程等待发送节点进行链接发送资源,进行资源的接收。
public class ReceiveDeal implements Runnable{
private Consumer consumer;
private ResourceInfo ri;
private CilentProxy cp;
private rmiCilent rc;
private static NetNode self = new NetNode();
private progressView view;
private boolean showProcess;//是否设置进度条
private List<NetNode> nodelist;
private List<List<FileHead>> headList;
static {
self.setIp(getSelfIp());
self.setPort(PortPo