多对等连接:对等连接有时会失败:收到邀请响应,但我们从未向它发送邀请。中止
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:对等方重置连接)
AWS ElasticBeanstalk NodeJS-502错误:从上游读取响应头时,recv()失败(104:对等连接重置)