在两个Peer之间发送消息

说明:这篇文章是我翻译JXTA programer's guid中的,在2.5版本中也有这个内容,不过在章节编制上有出入。由于最近正学习如何在两个Peer之间如何传送消息,故没有按照章节顺序,而是先看了这篇文章,并翻译出来供大家学习。

   另外,一直没搞明白文章中有图片时,为何粘贴到这里后就看不到图片了,知道的话请站内告诉我。需要看这些图片的话,就请直接下载JXTA programmer's guid.pdf文件看图片。

 

在两个Peer之间发送消息

 

在这部分,通过实例说明如何用Pips来在两个Peer之间传送消息。同时也展示了如何实例化RendezvousListener接口。这部分的例子由两个应用程序组成:

PipeListener---从一个文件((examplepipe.adv)中读入一个管道通告(pipe advertisement),创建一个输入管道。并监听这个管道上的消息。

PipeExample---从一个文件((examplepipe.adv)中读入一个管道通告(pipe advertisement),创建一个输出管道,并通过这个管道发送一个消息。

当这两个应用程序运行后,都会在控制台输出一些必要的信息以显示程序运行状态。PipeListener应用程序会输出这些信息:

PipeExample应用会输出这些信息:

注意:如果你是在同一台计算机上运行这两个程序,那你应该让它们两个在不同的文件夹中运行,这样可以使得它们使用不同的端口。

在看应用程序之前,下面先介绍一些有关JXTA中“管道服务”、“输入管道”和“输出管道”的背景知识。

管道服务(JXTA Pipe Service):

类PipeService定义了一组如何在一个对等组中创建和访问管道的接口。管道(Pipe)是在两个JXTA应用或服务之间传递消息的核心机制。管道为两个对等的之间通信提供了一个简单的、非直接的、异步的通道,JXTA消息就是在输入管道和输出管道直接进行交换传递。一个应用程序如果想从其它对等点那里接受消息,那么它就应该创建一个输入管道,并且将这个管道同某一个管道通告(Pipe Advertisement)绑定起来。最后,它还要发布这个通告。这样,其它想与它通信的对等点或者服务就可以创建相应的输出管道,以便发送消息。

管道在JXTA网络中有一个唯一的ID,即PipeId (UUID),以和其它管道区别开来。这个ID被封装在管道通告中。输入管道和输出管道就是通过这个PipeId 关联起来的。

在PipeListener和PipeExample应用程序用到了下面这些类:

net.jxta.pipe.PipeService---定义了管道服务的API

net.jxta.pipe.InputPipe---定义了从PipeService中接收消息的接口。一个应用程序要从管道中接收消息,就应该先创建输入管道。而输入管道InputPipe就是从PipeService中创建和返回的。

net.jxta.pipe.PipeMsgListener---监听PipeMsgEvent事件的监听接口

net.jxta.pipe.PipeMsgEvent---包含了从管道中接收的事件

net.jxta.pipe.OutputPipe---定义了从PipeService发送消息的接口。一个应用程序要向管道中发送消息,就应该先从PipeService中获得一个OutputPipe。

net.jxta.pipe.OutputPipeListener---OutputPipe事件的监听接口

net.jxta.pipe.OutputPipeEvent---包含了处理输出管道时所得到的的事件

net.jxta.endpoint.Message---定义了利用PipeService API所接收或者发送的消息的接口。一个消息包含了一组消息元素(MessageElements),每一个消息元素又包含了“名字空间”、“名称”、“数据”和“签名”等几项。

管道监听器(PipeListener)

这部分的应用程序创建了消息,并且在输入管道上监听这个消息。它只定义了一个类PipeListener,这个类实现了PipeMsgListener接口,这两个类常量包含了将要创建的管道的相关信息:

String FILENAME ---这是一个XML文件,包含了一些以文本形式表示的管道通告的内容(这个文件必须存在,并且必须包含一个可用的管道通告,否则程序就无法正常运行)。

String TAG ---消息元素的名字,或者标签。我们接收任何消息都要用到这些标签。

我们同时也定义了四个变量:

PeerGroup netPeerGroup ---默认的对等组

PipeService pipeSvc ---这是管道服务,我们要用它来创建输入管道并且监听消息

PipeAdvertisement pipeAdv ---管道通告,我们创建输入管道时用到它。

InputPipe pipeIn ---我们所创建的输入管道

main()方法

这个方法创建一个PipeListener对象。调用startJxta()方法来初始化JXTA平台,创建默认的对等组。然后调用run()方法,该方法中创建一个输入管道,并将之注册为PipeMsgListener。

startJxta()方法:

初始化JXTA平台,创建默认的对等组:

netPeerGroup = PeerGroupFactory.newNetPeerGroup();

然后从默认的对等组中获取管道服务,在后面创建输入管道时要用到这个服务:

pipeSvc = netPeerGroup.getPipeService();

接着,通过读入文件examplepipe.adv来创建一个管道通告:

FileInputStream is = new FileInputStream(FILENAME);

要注意文件examplepipe.adv必须存在,并且是合法可用的XML文件,包含一个管道通告,否则程序会发生例外。当前这个程序要创建一个输入管道,想对应了另一个程序要创建一个输出管道,它们两个都要读这个文件。这个文件的内容会在后面给出。

通过调用AdvertisementFactory.newAdvertisement()方法来创建一个管道通告:

pipeAdv = (PipeAdvertisement)AdvertisementFactory.newAdvertisement

(MimeMediaType.XML_DEFAULTENCODING, is);

run()方法:

在这个方法中,通过PipeService.createInputPipe()来创建一个输入管道:

pipeIn = pipeSvc.createInputPipe(pipeAdv, this);

由于我们还要监听这个输入管道的事件,所以调用createInputPipe()方法时有两个参数:

PipeAdvertisement adv---要创建的管道的通告

PipeMsgListener listener---接收输入管道事件的对象

在创建这个输入管道的时候,就把程序自身注册为监听器。所以,在这个管道中任何时候有消息事件pipeMsgEvent时(例如一个消息到来时),程序就以异步方式自动调用方法pipeMsgEvent()。

pipeMsgEvent()方法:

任何时候在输入管道中有管道事件发生时,该方法就被调用,是以异步方式的。该方法只有一个参数:

PipeMsgEvent event---发生在管道中的事件

在该方法中,首先调用PipeMsgEvent.getMessage()获取消息:

msg = event.getMessage();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现两个ESP8266-01S之间的通信,你可以使用ESP-NOW协议。ESP-NOW是ESP8266的一种通信协议,可以在两个或多个ESP8266之间快速建立低功耗的直连网络。 以下是一个简单的示例代码,演示了如何使用ESP-NOW在两个ESP8266-01S之间发送和接收数据: 首先,将以下代码上传到第一个ESP8266-01S上: ```cpp #include <ESP8266WiFi.h> #include <espnow.h> // 设置ESP-NOW发送回调函数 void OnDataSent(uint8_t* mac_addr, uint8_t sendStatus) { Serial.println("数据已发送"); } void setup() { Serial.begin(115200); // 初始化ESP-NOW if (esp_now_init() != 0) { Serial.println("ESP-NOW初始化失败"); return; } // 注册发送回调函数 esp_now_register_send_cb(OnDataSent); // 注册对方的MAC地址 uint8_t receiverMac[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB}; esp_now_peer_info_t peerInfo; memcpy(peerInfo.peer_addr, receiverMac, 6); peerInfo.channel = 0; peerInfo.encrypt = false; // 添加对方为配对设备 if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("添加配对设备失败"); return; } } void loop() { // 发送数据 String message = "Hello from ESP8266-01S #1"; esp_now_send(NULL, (uint8_t*)message.c_str(), message.length()); delay(1000); } ``` 接下来,将以下代码上传到第二个ESP8266-01S上: ```cpp #include <ESP8266WiFi.h> #include <espnow.h> // 设置ESP-NOW接收回调函数 void OnDataRecv(uint8_t* mac_addr, uint8_t* data, uint8_t len) { Serial.print("接收到的数据: "); for (int i = 0; i < len; i++) { Serial.print((char)data[i]); } Serial.println(); } void setup() { Serial.begin(115200); // 初始化ESP-NOW if (esp_now_init() != 0) { Serial.println("ESP-NOW初始化失败"); return; } // 注册接收回调函数 esp_now_register_recv_cb(OnDataRecv); // 注册对方的MAC地址 uint8_t senderMac[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB}; esp_now_peer_info_t peerInfo; memcpy(peerInfo.peer_addr, senderMac, 6); peerInfo.channel = 0; peerInfo.encrypt = false; // 添加对方为配对设备 if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("添加配对设备失败"); return; } } void loop() { // 循环执行 } ``` 在代码中,你需要根据实际情况修改`receiverMac`和`senderMac`的值,分别设置第一个ESP8266-01S和第二个ESP8266-01S的MAC地址。 上传完代码后,打开串口监视器,你将看到第一个ESP8266-01S每秒发送一条消息,并且第二个ESP8266-01S会接收并打印该消息。 这样,你就成功实现了两个ESP8266-01S之间的互相通信。你可以根据需要修改代码来发送和接收不同的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值