多对等连接:对等连接有时会失败:收到邀请响应,但我们从未向它发送邀请。中止

Posted

技术标签:

【中文标题】多对等连接:对等连接有时会失败:收到邀请响应,但我们从未向它发送邀请。中止【英文标题】:Multipeer Connectivity: Peer connect fails sometimes: Received an invitation response, but we never sent it an invitation. Aborting 【发布时间】:2016-12-07 10:46:22 【问题描述】:

我正在开发一个使用 MPC 的应用。有时它可以工作,A 和 B 客户端连接起来就像一个魅力,但有时连接失败,我从 MCNearbyServiceBrowser 收到奇怪的错误。

首先,我在 A 和 B 设备上初始化广告商、浏览器和会话。

 _peerID = [[MCPeerID alloc] initWithDisplayName:uniqueId];
 session = [[MCSession alloc] initWithPeer:_peerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
 session.delegate = self;

 NSDictionary *dict = @@“uniqueId” : uniqueId;
 _advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:_peerID discoveryInfo:dict  serviceType:@“my-app”];
 _advertiser.delegate = self;

 _browser = [[MCNearbyServiceBrowser alloc] initWithPeer:_peerID serviceType:@“my-app”];
 _browser.delegate = self;

 [_advertiser startAdvertisingPeer];
 [_browser startBrowsingForPeers];

A 和 B 有一个唯一的 ID,用于决定哪个设备应该邀请对方,以及哪个设备应该接受邀请(必须防止 A 和 B 同时邀请对方)。他们找到对方后,找到了对等的 MCNearbyServiceBrowser 委托调用。设备的 uniqueId 较少,它会发送邀请请求。

-(void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary<NSString *,NSString *> *)info 
    if (![[session connectedPeers] containsObject:peerID]) 
        NSInteger targetUniqueId = [[peerID displayName] integerValue];
        NSInteger myUniqueId = [uniqueId integerValue];

        if(myUniqueId<targetUniqueId)
          NSLog(@“invitation sent”);
          [browser invitePeer:peerID toSession:session withContext:nil timeout:inviteTimeout];
        
    

接受邀请(在 B 设备上调用):

-(void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession * _Nonnull))invitationHandler 
    NSInteger targetUniqueId = [[peerID displayName] integerValue];
    NSInteger myUniqueId = [uniqueId integerValue];
        if(myUniqueId>targetUniqueId)
          NSLog(@“accepting invitation”);
          invitationHandler(YES, session);
        

还实现了这样的证书处理程序(一些帖子抱怨它,如果不实现它也可能导致连接问题,而无需使用安全身份):

-(void)session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL))certificateHandler 
    certificateHandler(YES);

我记录了两个设备,然后:

    设备 A:已发送邀请 设备 B:接受邀请 设备 A:[MCNearbyServiceBrowser] 收到来自 [3362,090D4987] 的邀请响应,但我们从未向它发送邀请。中止!

几秒钟后,当未连接时,我停止浏览对等方,然后再次开始浏览。找到对等点后,我再次尝试建立相同的连接,重新邀请设备 B 上的对等点,接受邀请的对象。结果可能相同,或者连接状态切换为已连接。这是2个选项。有时设备可以在第一次尝试或少于 3 次尝试后连接,但有时在多次尝试后。上次他们在大约 40 条中止消息后可以连接,建立连接大约需要 15 分钟。

我做错了什么,为什么设备 A 对自己的邀请一无所知?

【问题讨论】:

嘿伙计!我在这里遇到同样的问题...你解决了吗?如何?提前致谢。 【参考方案1】:

一个 MCPeerID 有一个哈希值成员。您可以直接比较它们。

使用相同显示名称创建的两个 MCPeerID 对象不会具有相同的哈希值。这是为了防止名称冲突。

如果您想识别并被先前连接的对等方识别,您必须保存和恢复实际的 MCPeerID 对象。

将以下代码粘贴到 Playground 中并运行它以了解我的意思。

import MultipeerConnectivity

let hostName = "TestPlaygroundHostName"

let firstPeerID = MCPeerID(displayName: hostName)
let secondPeerID = MCPeerID(displayName: hostName)

firstPeerID.hashValue == secondPeerID.hashValue

【讨论】:

以上是关于多对等连接:对等连接有时会失败:收到邀请响应,但我们从未向它发送邀请。中止的主要内容,如果未能解决你的问题,请参考以下文章

nginx tomcat7 错误:-“从上游读取响应标头时,recv() 失败(104:对等连接重置)”

在 docker 和 ubuntu 中从上游读取响应标头时失败(104:对等方重置连接)

从上游读取响应头时失败(104:由对等方重置连接)

AWS ElasticBeanstalk NodeJS-502错误:从上游读取响应头时,recv()失败(104:对等连接重置)

对等方重置连接-同时使用 nginx 和 php-fpm7.2 从上游读取响应标头

蓝牙连接立即断开多点框架