MultipeerConnectivity 会话管理

Posted

技术标签:

【中文标题】MultipeerConnectivity 会话管理【英文标题】:MultipeerConnectivity Session management 【发布时间】:2013-11-02 14:19:33 【问题描述】:

我现在真的被困在试图掌握 MultipeerConnectivityFramework 中的邀请。

现在我有一个充当广告商的 ipad 应用程序和一个充当浏览器的 iphone 应用程序。 我已经为 MultipeerFramework 实现了一个 sharedService 并执行了以下操作:

广告商

@implementation MultipeerConnectivityService 
    MCNearbyServiceAdvertiser *_advertiser;
    MCSession *_session;
    MCNearbyServiceBrowser *_browser;        


- (void)automaticAdvertiseWithName:(NSString *)name 
    MCPeerID *peerID = [[MCPeerID alloc] initWithDisplayName:name];
    _session = [[MCSession alloc] initWithPeer:peerID];
    _session.delegate = self;

    _advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:peerID discoveryInfo:nil serviceType:kServiceType];
    _advertiser.delegate = self;
    [_advertiser startAdvertisingPeer];


- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler 
    invitationHandler([@YES boolValue], _session);
    NSLog(@"Invitation accepted");

浏览器

- (void)automaticBrowsingWithName:(NSString *)name 
    MCPeerID *peerID = [[MCPeerID alloc] initWithDisplayName:name];
    _browser = [[MCNearbyServiceBrowser alloc] initWithPeer:peerID serviceType:kServiceType];
    _browser.delegate = self;
    [_browser startBrowsingForPeers];


- (void)browser:(MCNearbyServiceBrowser *)browser didNotStartBrowsingForPeers:(NSError *)error 
    if ([_delegate respondsToSelector:@selector(browser:didNotStartBrowsingForPeers:)]) 
        [_delegate browserDidNotStartBrowsingForPeers];
    

- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info 
    [browser invitePeer:peerID toSession:[self getMCSession] withContext:nil timeout:10];
    if ([_delegate respondsToSelector:@selector(browser:foundPeer:)]) 
        [_delegate browser:browser foundPeer:peerID];
    

- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID 
    if ([_delegate respondsToSelector:@selector(browserLostPeer:)]) 
        [_delegate browserLostPeer:peerID];
    


- (MCSession *) getMCSession 
    return _session;

但后来我在控制台中得到反馈:

-[MCNearbyServiceBrowser invitePeer:toSession:withContext:timeout:] Bad argument session=nil

当我检查找到的广告商时,一切正常。正在找到我的广告客户 ipad。但是如何管理邀请?

所以我现在不明白...当我通过浏览器发送邀请时,我必须使用什么会话?在 iPad 上,我设置了会话,就像您在“automaticAdvertiseWithName”方法中看到的那样。但是在 iphone 上调用“automaticBrowsingWithName”时我不这样做......这是问题吗?他们不是必须是同一个会话才能成功连接它们吗?以及如何成功邀请我的广告客户 ipad 访问浏览器?

我对在广告商已经创建会话时创建新会话的概念感到困惑。

我实际上不确定,如果委托 didReceiveInvitation 是否将对等方添加到 connectedPeers 中。

- (void)automaticAdvertiseWithName:(NSString *)name 
    MCPeerID *peerID = [[MCPeerID alloc] initWithDisplayName:name];
    self.session = [[MCSession alloc] initWithPeer:peerID];
    self.session.delegate = self;
    _advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:peerID discoveryInfo:nil serviceType:kServiceType];
    _advertiser.delegate = self;
    [_advertiser startAdvertisingPeer];

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler 
    BOOL accept = YES;
    invitationHandler(accept, self.session);
    NSLog(@"Invitation accepted: %@", self.session);

当我在会话中调用属性“connectedPeers”时,根本没有连接的对等点,即使委托人找到了。我是不是搞错了?

【问题讨论】:

【参考方案1】:

您的问题是在您调用invitePeer:toSession:withContext:timeout 时您的会话为空...无论如何您有两个选项可以解决此问题。

您有两个选项:选项 1 - 将 peerID 创建会话创建会话委托分配 移动到一直执行的位置。例如在 MultipeerConnectivityService 类的初始化代码中,如果它是 viewDidLoad 中的 UIViewController。选项 2 - 在调用“invitePeer:toSession:withContext:timeout:”之前添加以下 sn-p

if (!_session) 
      MCPeerID *peerID = [[MCPeerID alloc] initWithDisplayName:@"Browser"]; // you can customize the name here
     _session = [[MCSession alloc] initWithPeer:peerID];
     _session.delegate = self;

希望这会有所帮助……祝你好运!

【讨论】:

谢谢!!我选择了选项 2,效果很好!一开始,会议的概念有点难以理解。我一直认为我必须为两者使用相同的会话.... 很高兴选项 2 有帮助! 我也对此感到困惑。我知道浏览器旨在将对等点添加到其会话中,但我仍然不确定广告商的正确意图是什么。目前我只是假设当广告商在invitationHandler 中提供一个会话时,它会以某种方式与浏览器添加它的会话“合并”。 @Beuz 或 @ISARFAKTOR,如果您对此有见解,请分享。 实际上我看到的方式是,虽然您通常在同一类中为浏览逻辑和广告逻辑编写代码,但是当使用该程序时,您有两个不同的设备和 1 个完全独立的会话每个。 浏览器从那里发现广告会话并邀请广告商参与其自己的会话。其余的发生在浏览器的会话中。此时的广告商只是浏览器会话的参与者。 我同意这有点令人困惑,因为您会认为广告商就像一个人们会加入的服务器。但它似乎只是一种展示你的存在的方式,以便其他人可以邀请你......希望这会有所帮助。

以上是关于MultipeerConnectivity 会话管理的主要内容,如果未能解决你的问题,请参考以下文章

从 Connecting 到 NotConnected 的 Multipeer Connectivity 会话

如何使用 Multipeer Connectivity (Swift 3) 在会话中通过 didReceiveData() 调用 table.reloadData

多点连接终止会话

通过BackgroundTask在后台维护多路连接会话?

iOS 7:多点连接 - 多个会话?

多点连接 - 以编程方式断开对等点