⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipeutil.java

📁 可以实现P2P聊天通信
💻 JAVA
字号:
package jxtamessenger.util;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.logging.Logger;

import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.id.IDFactory;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.PipeID;
import net.jxta.protocol.PipeAdvertisement;

import org.apache.commons.lang.StringUtils;

public class PipeUtil {
	private static final Logger LOG = Logger.getLogger(PipeUtil.class.getName());
	
	private static final int WaitTime = 500;		// 远程发现的等待时间,需根据网络情况调整
	private static final int MAXRETRIES = 20;		// 远程发现时的重试次数,需根据网络情况调整
	
	/**
	 * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,再从远程发现管道广告,如果没有发现,那么创建管道广告。
	 * @param pg		用于发现或创建管道广告的节点组
	 * @param name		用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
	 * @param type		创建管道广告的类型,目前支持3种基本类型
	 * 						JxtaUnicast			单向、不安全和不可靠
	 * 						JxtaUnicastSecure	单向、安全(使用TLS)
	 * 						JxtaPropagate		传播广告 
	 * @param pipeId	指定生成管道广告的PipeId,如果该值为空或null,那么使用系统生成的Id
	 * @param remote	如果创建管道广告,那么是否远程发布
	 * @return			在节点组内发现或创建的广告对象
	 */
	public static PipeAdvertisement getPipeAdv(PeerGroup pg, String name, String type, String pipeId, boolean remote) {
		PipeAdvertisement myAdv = null;
		
		try {
			myAdv = findPipeAdv(pg, name);
			
			if(myAdv == null) {
				// We did not find the pipe advertisement, so create one
				LOG.info("Could not find the Pipe Advertisement");
				
				// Create a pipe advertisement
				myAdv = createAdv(pg, name, type, pipeId);
				
				// We have the advertisement; publish it into our local cache or remote peer
				publish(pg, myAdv, remote);
				
				LOG.info("Created the Pipe Advertisement");
			}
		} catch(Exception e) {
			LOG.severe("Could not get pipe Advertisement");
			return null;
		}
		
		return myAdv;
	}
	
	/**
	 * 同步方式发现管道广告
	 * @param pg	节点组,在该节点组内发现管道广告
	 * @param name	管道广告名称,可使用通配符
	 * @return		管道广告对象,如果没有找到或发现过程发生异常,那么返回null
	 */
	public static PipeAdvertisement findPipeAdv(PeerGroup pg, String name) {
		DiscoveryService discovery = pg.getDiscoveryService();
		
		int count = MAXRETRIES; // Discovery retry count
		
		PipeAdvertisement myAdv = null;
		
		try {
			LOG.info("Attempting to Discover the pipe advertisement");
			
			// Check if we have already published ourselves
			while(count-- > 0) {
				// First, check locally if the advertisement is cached
				myAdv = searchLocal(pg, name);
				
				// If we found our pipe advertisement, we are done
				if(myAdv != null)
					break;

				// We did not find the advertisement locally;
				// send a remote request
				discovery.getRemoteAdvertisements(null, DiscoveryService.ADV, PipeAdvertisement.NameTag, name, 1, null);
				
				// Sleep to allow time for peers to respond to the discovery request
				try {
					Thread.sleep(WaitTime);
				} catch(InterruptedException e) {
					// ignored
				}
			}
		} catch(Exception e) {
			LOG.severe("Could not get pipe Advertisement");
			return null;
		}
		
		if(myAdv != null) {
			LOG.info(myAdv.toString());
		} else {
			LOG.info("myAdv is null.");
		}
		
		return myAdv;
	}
	
	/**
	 * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,再从远程发现管道广告,如果没有发现,那么使用系统生成的Id创建管道广告。
	 * @param pg		用于发现或创建管道广告的节点组
	 * @param name		用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
	 * @param type		创建管道广告的类型,目前支持3种基本类型
	 * 						JxtaUnicast			单向、不安全和不可靠
	 * 						JxtaUnicastSecure	单向、安全(使用TLS)
	 * 						JxtaPropagate		传播广告 
	 * @param remote	如果创建管道广告,那么是否远程发布
	 * @return			在节点组内发现或创建的广告对象
	 */
	public static PipeAdvertisement getPipeAdv(PeerGroup pg, String name, String type, boolean remote) {
		return getPipeAdv(pg, name, type, null, remote);
	}
	
	/**
	 * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,那么创建管道广告。
	 * @param pg		用于发现或创建管道广告的节点组
	 * @param name		用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
	 * @param type		创建管道广告的类型,目前支持3种基本类型
	 * 						JxtaUnicast			单向、不安全和不可靠
	 * 						JxtaUnicastSecure	单向、安全(使用TLS)
	 * 						JxtaPropagate		传播广告 
	 * @param pipeId	指定生成管道广告的PipeId,如果该值为空或null,那么使用系统生成的Id
	 * @param remote	如果创建管道广告,那么是否远程发布
	 * @return			在节点组内发现或创建的广告对象
	 */
	public static PipeAdvertisement getPipeAdvWithoutRemoteDiscovery(PeerGroup pg, String name, String type, String pipeId, boolean remote) {
        PipeAdvertisement pa = searchLocal(pg, name);

        if (pa == null) {
            pa = createAdv(pg, name, type, pipeId);

            publish(pg, pa, remote);
        }

        return pa;
	}
	
	/**
	 * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,再从远程发现管道广告,如果没有发现,那么使用系统生成的Id创建管道广告。
	 * @param pg		用于发现或创建管道广告的节点组
	 * @param name		用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
	 * @param type		创建管道广告的类型,目前支持3种基本类型
	 * 						JxtaUnicast			单向、不安全和不可靠
	 * 						JxtaUnicastSecure	单向、安全(使用TLS)
	 * 						JxtaPropagate		传播广告 
	 * @param remote	如果创建管道广告,那么是否远程发布
	 * @return			在节点组内发现或创建的广告对象
	 */
	public static PipeAdvertisement getPipeAdvWithoutRemoteDiscovery(PeerGroup pg, String name, String type, boolean remote) {
		return getPipeAdvWithoutRemoteDiscovery(pg, name, type, null, remote);
	}
	
	/**
	 * 创建管道广告
	 * @param pg		用于创建管道广告的节点组
	 * @param name		使用该名称创建管道广告
	 * @param type		创建管道广告的类型,目前支持3种基本类型
	 * 						JxtaUnicast			单向、不安全和不可靠
	 * 						JxtaUnicastSecure	单向、安全(使用TLS)
	 * 						JxtaPropagate		传播广告 
	 * @param pipeId	指定生成管道广告的PipeId,如果该值为空或null,那么使用系统生成的Id
	 * @return			在节点组内创建的广告对象
	 */
    public static PipeAdvertisement createAdv(PeerGroup pg, String name, String type, String pipeId) {
    	PipeAdvertisement pa = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());

    	try {
			pa.setPipeID(StringUtils.isEmpty(pipeId)?IDFactory.newPipeID(pg.getPeerGroupID()):(PipeID) IDFactory.fromURI(new URI(pipeId)));
	    	pa.setName(name);
	    	pa.setType(type);
		} catch (URISyntaxException e) {
			LOG.warning("a string could not be parsed as a URI reference");
			e.printStackTrace();
		}

    	return pa;
    }
	
    /**
     * 本地搜索广告对象
     * @param pg		用于搜索管道广告的节点组
     * @param name		用于搜索管道广告的名称,可使用通配符
     * @return			在节点组内创建的广告对象(仅返回第一个发现的管道广告)
     */
    public static PipeAdvertisement searchLocal(PeerGroup pg, String name) {

        DiscoveryService discoveryService = pg.getDiscoveryService();
        Enumeration<Advertisement> pas = null;
        try {
            pas = discoveryService.getLocalAdvertisements(DiscoveryService.ADV, PipeAdvertisement.NameTag, name);
        } catch (IOException e) {
            return null;
        }
        PipeAdvertisement pa = null;
        while (pas.hasMoreElements()) {
            pa = (PipeAdvertisement) pas.nextElement();

            if (pa.getName().equals(name)) {
                return pa;
            }
        }
        return null;
    }
	
    public static void publish(PeerGroup pg, PipeAdvertisement pa) {
        publish(pg, pa, false);
    }

    public static void publish(PeerGroup pg, PipeAdvertisement pa, boolean remote) {
        DiscoveryService ds = pg.getDiscoveryService();

        try {
            ds.publish(pa);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        if (remote) {
             ds.remotePublish(pa, DiscoveryService.ADV);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -