`

利用Pipe实现最简单的通信

阅读更多

本文主要讲解的是如何单纯发布管道广告,及利用发现的管道进行简单的信息通信。PeerServer发布管道广告,等待其它PeerClient发现及连接,然后向PeerServer发送一条内容为“你是谁”的信息。下面给出的两个类可以放在同个目录下运行。

public class PeerServer {

 private DiscoveryService discoveryService = null;

 private PipeService pipeService = null;

 private PeerGroup restoNet = null;

 private PeerGroupID peerGroupID = null;

 private InputPipe inputPipe = null;


 public static void main(String[] args) {
  Logger.getLogger("net.jxta").setLevel(Level.SEVERE);
  PeerServer peer1 = new PeerServer();
  peer1.launchJXTA();
 }

 private void launchJXTA() {
  try {
   NetworkConfigurator config = new NetworkConfigurator();//设置配置可以跳过第1次运行时出现的配置UI
   config.setPrincipal("peer1");// Peer名称
   config.setPassword("888888888");// Peer密码
   config.save();
   restoNet = new NetPeerGroupFactory().getInterface();
   peerGroupID = restoNet.getPeerGroupID();
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(-1);
  }
  discoveryService = restoNet.getDiscoveryService();// 取得NetPeerGroup的发现服务
  pipeService = restoNet.getPipeService();// 取得NetPeerGroup的管道服务
  startServer();// 开始启动
 }

 private void startServer() {
  publishPipeAdvertisement();// 发布管道广告
 }
 //创建及发布管道广告
 private void publishPipeAdvertisement() {
  PipeAdvertisement pipeAdv = createPipeAdvertisement();
  // -----------------以下这段代码只是为了把管道广告的内容打印出来--------------------------
  StructuredTextDocument doc = (StructuredTextDocument) pipeAdv
    .getDocument(MimeMediaType.XMLUTF8);
  StringWriter out = new StringWriter();
  try {
   doc.sendToWriter(out);
   System.out.println(out.toString());
   out.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
  // -----------------------------打印结束--------------------------------------------
  try {
   discoveryService.publish(pipeAdv);//本地发布管道广告
   discoveryService.remotePublish(pipeAdv);//远程发布管道广告
   inputPipe = pipeService.createInputPipe(pipeAdv);// 创建输入管道
  } catch (IOException e) {
   e.printStackTrace();
  }
  while (true) {
   System.out.println("等待其它Peer端信息的到达.........");
   Message msg;
   try {
    msg = inputPipe.waitForMessage();// 监听输入管道是否有信息传进来
   } catch (InterruptedException e) {
    inputPipe.close();
    System.out.println("接收其它Peer信息出错!");
    return;// 如果出现异常则返回
   }
   String receiveContent = null;
   Message.ElementIterator en = msg.getMessageElements();// 取得到信息
   if (!en.hasNext()) {
    return;
   }
   MessageElement msgElement = msg.getMessageElement(null, "DataTag");
   if (msgElement.toString() != null) {
    receiveContent = msgElement.toString();
   }
   if (receiveContent != null) {
    System.out.println("接收信息内容: "
      + receiveContent);
   } else {
    System.out
      .println("没有内容");
   }
  }
 }

 // 生成管道广告,在这里我们是直接从代码中生成管道广告,当然我们可以读管道广告文件
 private PipeAdvertisement createPipeAdvertisement() {
  PipeAdvertisement pipeAdvertisement = null;
  pipeAdvertisement = (PipeAdvertisement) AdvertisementFactory
    .newAdvertisement(PipeAdvertisement.getAdvertisementType());// 创建一个管道广告
  pipeAdvertisement.setPipeID(createPipeID(peerGroupID));
  pipeAdvertisement.setName("Pipe");
  pipeAdvertisement.setDescription("JXTA create first pipe");
  pipeAdvertisement.setType(PipeService.UnicastType);// 管道类型,管道类型在JXTA
  return pipeAdvertisement;
 }

 // 生成管道ID
 private PipeID createPipeID(PeerGroupID groupID) {
  PipeID pipeID = null;
  pipeID = IDFactory.newPipeID(groupID);
  return pipeID;
 }
}
先执行上面这个类,再执行下面PeerClient类。

public class PeerClient {

 private PeerGroup netpg = null;// PeerGroup

 private DiscoveryService disco; // 发现服务

 private PipeService pipeSev; // 管道服务

 private PipeAdvertisement pipeAdv = null;// 管道广告

 private OutputPipe outputPipe;// 输入管道

 public static void main(String[] args) {
  Logger.getLogger("net.jxta").setLevel(Level.SEVERE);
  PeerClient peer2 = new PeerClient();
  peer2.launchJXTA();
 }

 private void launchJXTA() {
  System.out.println("Lauching Peer into JXTA NetWork...");
  try {
   NetworkConfigurator config = new NetworkConfigurator();
   config.setPrincipal("peer2");
   config.setPassword("888888888");
   config.save();
   netpg = new NetPeerGroupFactory().getInterface();
  } catch (Exception e) {
   System.out.println("Unable to create PeerGroup - Failure");
   System.exit(-1);
  }
  startClient();
 }

 private void startClient() {
  System.out.println("搜索管道广告....");
  disco = netpg.getDiscoveryService();//获取NetGroup发现服务
  pipeSev = netpg.getPipeService();//获取NetGroup管道服务
  Enumeration en;
  while (true) {
   try {
    en = disco.getLocalAdvertisements(DiscoveryService.ADV, "Name",
      "Pipe");// 本地发现广告,后面对应了广告中Name标签,值为Pipe的管道广告
    if ((en != null) && en.hasMoreElements()) {
     break;
    }
    disco.getRemoteAdvertisements(null, DiscoveryService.ADV,
      "Name", "Pipe", 1, null);// 远程发现广告
    try {
     Thread.sleep(2000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
   System.out.print(".");
  }
  System.out.println("已经找到管道广告.......");
  pipeAdv = (PipeAdvertisement) en
  .nextElement();
  if (null == pipeAdv) {
   System.out.println("没有找到管道广告");
  }
  try {
   outputPipe = pipeSev.createOutputPipe(pipeAdv, 10000);// 创建输出管道,其实是连接Peer1中的输入管道
  } catch (IOException e) {
   e.printStackTrace();
  }
  String data = "你是谁";// 我们要发送的信息内容
  Message msg = new Message();

  StringMessageElement sme = new StringMessageElement("DataTag", data,
    null);
  msg.addMessageElement(null, sme);
  try {
   outputPipe.send(msg);// 发送信息
   System.out.println("信息 \"" + data
     + "\" 已经发送");
  } catch (IOException e) {
   e.printStackTrace();
   System.out
     .println("发送信息失败!!");
  }

 }

}

0
0
分享到:
评论
9 楼 A11819 2012-11-16  
heyiwen871220 写道
Output Pipe could not be resolved after 10000ms.我也是这个错误。。。高手,指点下吧...555

我也发现了这个问题,第一次启动可以成功,第二次就报错了。我是把项目文件夹下面的".jxta"文件夹删除了再启动就好了,现在还没弄清楚到底什么原因。
8 楼 heyiwen871220 2011-11-23  
Output Pipe could not be resolved after 10000ms.我也是这个错误。。。高手,指点下吧...555
7 楼 leigous 2011-04-20  
lyndon.lin 写道
你所谓的远程是指?那种,网络的,还是只是不同机的。不过经过其他人测试说,直接这个说远程连接不上,要用标准的方法来连接。即把管道广告包含在实现广告中发布。

实现广告是什么意思?
6 楼 leigous 2011-04-19  
你好我用你上面的两个程序进行了测试,第一运行能成功,当我关了PeerServer再开时,运行PeerClient就会出现
Lauching Peer into JXTA NetWork...
搜索管道广告....
已经找到管道广告.......
java.io.IOException: Output Pipe could not be resolved after 10000ms.
        at net.jxta.impl.pipe.PipeServiceImpl.createOutputPipe(PipeServiceImpl.java:459)
        at net.jxta.impl.pipe.PipeServiceImpl.createOutputPipe(PipeServiceImpl.java:416)
        at net.jxta.impl.pipe.PipeServiceInterface.createOutputPipe(PipeServiceInterface.java:160)
        at jxta_comunication.PeerClient.startClient(PeerClient.java:84)
        at jxta_comunication.PeerClient.launchJXTA(PeerClient.java:51)
        at jxta_comunication.PeerClient.main(PeerClient.java:36)
Exception in thread "main" java.lang.NullPointerException
        at jxta_comunication.PeerClient.startClient(PeerClient.java:95)
        at jxta_comunication.PeerClient.launchJXTA(PeerClient.java:51)
        at jxta_comunication.PeerClient.main(PeerClient.java:36)
应该就是Output连不上了。请问这是什么问题?
5 楼 lifeng_2009 2010-06-03  
lyndon.lin 写道
你所谓的远程是指?那种,网络的,还是只是不同机的。不过经过其他人测试说,直接这个说远程连接不上,要用标准的方法来连接。即把管道广告包含在实现广告中发布。

你好 我也通过你提示我的信息找了相关的资料,其中 即把管道广告包含在实现广告中发布。 我做了测试 这种情况只有两端都建立默认组的情况下才能实现。如果一方建立组 另外一方加入此组 就找不到PipeAdvertisement. 也不知道是什么情况导致的。难道两个PEER在默认组 和两个PEER在自己建立的peergroup 是不一样的、
4 楼 lyndon.lin 2010-05-28  
发现RDV其实是需要通过设定Seed来做的  要不然外网的RDV是无法发现:
config.addSeedRelay(new URI("http://192.168.0.9:9702"),10);
config.addSeedRendezvous(new URI("http://192.168.0.9:9702"),10);
3 楼 lifeng_2009 2010-05-28  
你好;
     可能是我说的不太清楚,我用你的例子在一个远程服务器上建立了服务端,也就是你写的PEERSERVER类 在服务端运行
我的客户端是在我公司的子网里面 现在在子网运行你的PEERCILENT类时 互相都搜索不到对方。
     另外像你这样的用代码跳过配置窗口。不用给服务器端配置Rendezvous 让服务器作为Rendezvous吗
我关于JXTA配置窗口的配置如下 不知道对不对 请牙哥指点下
服务器设置 在Basic 中 填写 peername 和 password
         在 Advanced 中把服务器设置为 Act as a Rendezvous
                  TCP Settings中 给Manual设置自己的IP 加9701端口
          在Rendezvous/Relays中 取消Use a rendezvous 和 Use a relay复选框
客户端设置
        在Basic 中 填写 peername 和 password
        在 Advanced 中 什么都不改
          在Rendezvous/Relays中
                    在 Use a rendezvous 的 Rendezvous seed peers中填写
                      tcp://服务器IP:9701 
                    取消 Use a relay复选框
我现在不清楚要是连接远程服务器是不是我配置的有问题。
你说的:“要用标准的方法来连接。即把管道广告包含在实现广告中发布。”
的标准方法连接是什么意思 普通连接是什么呢 。后面的意思有是什么呢?
我们平时发布广告不是用
DiscoveryService.publish 来发布本地广告
DiscoveryService.remotePublish  来发布远程广告
你说的实现广告中发布是什么意思呢?
                     
2 楼 lyndon.lin 2010-05-27  
你所谓的远程是指?那种,网络的,还是只是不同机的。不过经过其他人测试说,直接这个说远程连接不上,要用标准的方法来连接。即把管道广告包含在实现广告中发布。
1 楼 lifeng_2009 2010-05-27  
远程不通啊!

相关推荐

Global site tag (gtag.js) - Google Analytics