PipeUtil.java
上传用户:damzkj
上传日期:2022-01-07
资源大小:24k
文件大小:8k
源码类别:

P2P编程

开发平台:

Java

  1. package jxtamessenger.util;
  2. import java.io.IOException;
  3. import java.net.URI;
  4. import java.net.URISyntaxException;
  5. import java.util.Enumeration;
  6. import java.util.logging.Logger;
  7. import net.jxta.discovery.DiscoveryService;
  8. import net.jxta.document.Advertisement;
  9. import net.jxta.document.AdvertisementFactory;
  10. import net.jxta.id.IDFactory;
  11. import net.jxta.peergroup.PeerGroup;
  12. import net.jxta.pipe.PipeID;
  13. import net.jxta.protocol.PipeAdvertisement;
  14. import org.apache.commons.lang.StringUtils;
  15. public class PipeUtil {
  16. private static final Logger LOG = Logger.getLogger(PipeUtil.class.getName());
  17. private static final int WaitTime = 500; // 远程发现的等待时间,需根据网络情况调整
  18. private static final int MAXRETRIES = 20; // 远程发现时的重试次数,需根据网络情况调整
  19. /**
  20.  * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,再从远程发现管道广告,如果没有发现,那么创建管道广告。
  21.  * @param pg 用于发现或创建管道广告的节点组
  22.  * @param name 用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
  23.  * @param type 创建管道广告的类型,目前支持3种基本类型
  24.  *  JxtaUnicast 单向、不安全和不可靠
  25.  *  JxtaUnicastSecure 单向、安全(使用TLS)
  26.  *  JxtaPropagate 传播广告 
  27.  * @param pipeId 指定生成管道广告的PipeId,如果该值为空或null,那么使用系统生成的Id
  28.  * @param remote 如果创建管道广告,那么是否远程发布
  29.  * @return 在节点组内发现或创建的广告对象
  30.  */
  31. public static PipeAdvertisement getPipeAdv(PeerGroup pg, String name, String type, String pipeId, boolean remote) {
  32. PipeAdvertisement myAdv = null;
  33. try {
  34. myAdv = findPipeAdv(pg, name);
  35. if(myAdv == null) {
  36. // We did not find the pipe advertisement, so create one
  37. LOG.info("Could not find the Pipe Advertisement");
  38. // Create a pipe advertisement
  39. myAdv = createAdv(pg, name, type, pipeId);
  40. // We have the advertisement; publish it into our local cache or remote peer
  41. publish(pg, myAdv, remote);
  42. LOG.info("Created the Pipe Advertisement");
  43. }
  44. } catch(Exception e) {
  45. LOG.severe("Could not get pipe Advertisement");
  46. return null;
  47. }
  48. return myAdv;
  49. }
  50. /**
  51.  * 同步方式发现管道广告
  52.  * @param pg 节点组,在该节点组内发现管道广告
  53.  * @param name 管道广告名称,可使用通配符
  54.  * @return 管道广告对象,如果没有找到或发现过程发生异常,那么返回null
  55.  */
  56. public static PipeAdvertisement findPipeAdv(PeerGroup pg, String name) {
  57. DiscoveryService discovery = pg.getDiscoveryService();
  58. int count = MAXRETRIES; // Discovery retry count
  59. PipeAdvertisement myAdv = null;
  60. try {
  61. LOG.info("Attempting to Discover the pipe advertisement");
  62. // Check if we have already published ourselves
  63. while(count-- > 0) {
  64. // First, check locally if the advertisement is cached
  65. myAdv = searchLocal(pg, name);
  66. // If we found our pipe advertisement, we are done
  67. if(myAdv != null)
  68. break;
  69. // We did not find the advertisement locally;
  70. // send a remote request
  71. discovery.getRemoteAdvertisements(null, DiscoveryService.ADV, PipeAdvertisement.NameTag, name, 1, null);
  72. // Sleep to allow time for peers to respond to the discovery request
  73. try {
  74. Thread.sleep(WaitTime);
  75. } catch(InterruptedException e) {
  76. // ignored
  77. }
  78. }
  79. } catch(Exception e) {
  80. LOG.severe("Could not get pipe Advertisement");
  81. return null;
  82. }
  83. if(myAdv != null) {
  84. LOG.info(myAdv.toString());
  85. } else {
  86. LOG.info("myAdv is null.");
  87. }
  88. return myAdv;
  89. }
  90. /**
  91.  * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,再从远程发现管道广告,如果没有发现,那么使用系统生成的Id创建管道广告。
  92.  * @param pg 用于发现或创建管道广告的节点组
  93.  * @param name 用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
  94.  * @param type 创建管道广告的类型,目前支持3种基本类型
  95.  *  JxtaUnicast 单向、不安全和不可靠
  96.  *  JxtaUnicastSecure 单向、安全(使用TLS)
  97.  *  JxtaPropagate 传播广告 
  98.  * @param remote 如果创建管道广告,那么是否远程发布
  99.  * @return 在节点组内发现或创建的广告对象
  100.  */
  101. public static PipeAdvertisement getPipeAdv(PeerGroup pg, String name, String type, boolean remote) {
  102. return getPipeAdv(pg, name, type, null, remote);
  103. }
  104. /**
  105.  * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,那么创建管道广告。
  106.  * @param pg 用于发现或创建管道广告的节点组
  107.  * @param name 用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
  108.  * @param type 创建管道广告的类型,目前支持3种基本类型
  109.  *  JxtaUnicast 单向、不安全和不可靠
  110.  *  JxtaUnicastSecure 单向、安全(使用TLS)
  111.  *  JxtaPropagate 传播广告 
  112.  * @param pipeId 指定生成管道广告的PipeId,如果该值为空或null,那么使用系统生成的Id
  113.  * @param remote 如果创建管道广告,那么是否远程发布
  114.  * @return 在节点组内发现或创建的广告对象
  115.  */
  116. public static PipeAdvertisement getPipeAdvWithoutRemoteDiscovery(PeerGroup pg, String name, String type, String pipeId, boolean remote) {
  117.         PipeAdvertisement pa = searchLocal(pg, name);
  118.         if (pa == null) {
  119.             pa = createAdv(pg, name, type, pipeId);
  120.             publish(pg, pa, remote);
  121.         }
  122.         return pa;
  123. }
  124. /**
  125.  * 获取管道广告,首先从本地缓存中发现管道广告,如果没有发现,再从远程发现管道广告,如果没有发现,那么使用系统生成的Id创建管道广告。
  126.  * @param pg 用于发现或创建管道广告的节点组
  127.  * @param name 用于发现或创建管道广告的名称,如果本地或远程都没有发现管道广告,那么将使用该名称创建管道广告,因此该名称不要使用通配符
  128.  * @param type 创建管道广告的类型,目前支持3种基本类型
  129.  *  JxtaUnicast 单向、不安全和不可靠
  130.  *  JxtaUnicastSecure 单向、安全(使用TLS)
  131.  *  JxtaPropagate 传播广告 
  132.  * @param remote 如果创建管道广告,那么是否远程发布
  133.  * @return 在节点组内发现或创建的广告对象
  134.  */
  135. public static PipeAdvertisement getPipeAdvWithoutRemoteDiscovery(PeerGroup pg, String name, String type, boolean remote) {
  136. return getPipeAdvWithoutRemoteDiscovery(pg, name, type, null, remote);
  137. }
  138. /**
  139.  * 创建管道广告
  140.  * @param pg 用于创建管道广告的节点组
  141.  * @param name 使用该名称创建管道广告
  142.  * @param type 创建管道广告的类型,目前支持3种基本类型
  143.  *  JxtaUnicast 单向、不安全和不可靠
  144.  *  JxtaUnicastSecure 单向、安全(使用TLS)
  145.  *  JxtaPropagate 传播广告 
  146.  * @param pipeId 指定生成管道广告的PipeId,如果该值为空或null,那么使用系统生成的Id
  147.  * @return 在节点组内创建的广告对象
  148.  */
  149.     public static PipeAdvertisement createAdv(PeerGroup pg, String name, String type, String pipeId) {
  150.      PipeAdvertisement pa = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());
  151.      try {
  152. pa.setPipeID(StringUtils.isEmpty(pipeId)?IDFactory.newPipeID(pg.getPeerGroupID()):(PipeID) IDFactory.fromURI(new URI(pipeId)));
  153.      pa.setName(name);
  154.      pa.setType(type);
  155. } catch (URISyntaxException e) {
  156. LOG.warning("a string could not be parsed as a URI reference");
  157. e.printStackTrace();
  158. }
  159.      return pa;
  160.     }
  161.     /**
  162.      * 本地搜索广告对象
  163.      * @param pg 用于搜索管道广告的节点组
  164.      * @param name 用于搜索管道广告的名称,可使用通配符
  165.      * @return 在节点组内创建的广告对象(仅返回第一个发现的管道广告)
  166.      */
  167.     public static PipeAdvertisement searchLocal(PeerGroup pg, String name) {
  168.         DiscoveryService discoveryService = pg.getDiscoveryService();
  169.         Enumeration<Advertisement> pas = null;
  170.         try {
  171.             pas = discoveryService.getLocalAdvertisements(DiscoveryService.ADV, PipeAdvertisement.NameTag, name);
  172.         } catch (IOException e) {
  173.             return null;
  174.         }
  175.         PipeAdvertisement pa = null;
  176.         while (pas.hasMoreElements()) {
  177.             pa = (PipeAdvertisement) pas.nextElement();
  178.             if (pa.getName().equals(name)) {
  179.                 return pa;
  180.             }
  181.         }
  182.         return null;
  183.     }
  184.     public static void publish(PeerGroup pg, PipeAdvertisement pa) {
  185.         publish(pg, pa, false);
  186.     }
  187.     public static void publish(PeerGroup pg, PipeAdvertisement pa, boolean remote) {
  188.         DiscoveryService ds = pg.getDiscoveryService();
  189.         try {
  190.             ds.publish(pa);
  191.         } catch (IOException ioe) {
  192.             ioe.printStackTrace();
  193.         }
  194.         if (remote) {
  195.              ds.remotePublish(pa, DiscoveryService.ADV);
  196.         }
  197.     }
  198. }