【问题标题】:Connect 3rd Device using GameKit使用 GameKit 连接第三台设备
【发布时间】:2011-03-31 17:57:42
【问题描述】:

我现在在基本级别上使用 GameKit。我能够连接两个设备并在它们之间发送消息。

我有 3 台设备,我们称它们为设备 A、B 和 C。

我能够将 A 连接到 B、A 连接到 C 以及 B 连接到 C,作为单独的设置。

如果我将 A 连接到 B,然后尝试将 B 连接到 C,设备 C 将显示设备 B 可用,但设备 B 继续旋转并说“正在寻找可用的 iPod、iPhone...”

peerPickerController:sessionForConnectionType: 中,当我尝试将 B 连接到 C 时,我试图让设备 B 重用它在连接到 A 时使用的相同 GKSession... 因为如果我创建一个新会话在设备 B 上,它能够连接到设备 C,但断开与设备 A 的连接。

这里是sessionForConnectionType

 -(GKSession*)peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type {

   // session is a synthesized GKSession
        if (session == nil) {
            session = [[GKSession alloc] initWithSessionID:nil  displayName:@"" sessionMode:GKSessionModePeer];
            session.delegate = self;        
        } 


        return session;
    }

【问题讨论】:

    标签: iphone gamekit gksession


    【解决方案1】:

    我最终选择了更易于管理的服务器/客户端设置。这样,只有一个 Server PeerID,而不是每个连接都有一个 Server PeerID。我找不到很多好的例子,所以我在这里包含了基本的 GameKit 服务器/客户端代码。

    // if the device in an ipad, treat it as a host / server
    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPad"]) {
            isHost = YES;
        } else {
            isHost = NO;
        }
    
    // monitor if this device is connected to another device
        isConnected = NO;
    }
    
    
    
    
    #pragma mark GameKit Methods
    
    // Called when a change in the connection state is detected
    - (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
    
        NSLog(@"Session:Peer:%@ Did Change State", peerID);
         Globals *globals = [Globals shareData];
    
        switch (state) {
            case GKPeerStateConnected:
                NSLog(@"GKPeerStateConnected");
    
                [globals.localSession setDataReceiveHandler:self withContext:nil];
    
    // if this device is not the host and is not connected yet...
                if (!isHost && !isConnected) {
    
    // update variables, save the Server PeerId and the local Session so we can use them later 
                    isConnected = YES;
                    serverSession = peerID];
                    localSession = session;
                }
                break;
    
            case GKPeerStateDisconnected:
                NSLog(@"GKPeerStateDisconnected");
                break;
    
            case GKPeerStateAvailable:
                NSLog(@"GKPeerStateAvailable");
                if (!isHost) {
                    NSLog(@"Attempting to Connect...");
    // the server is available, try to connect to it
                    [session connectToPeer:peerID withTimeout:20];
                }
                break;
    
            case GKPeerStateConnecting:
                NSLog(@"GKPeerStateConnecting");
                break;
    
            case GKPeerStateUnavailable:
                NSLog(@"GKPeerStateUnavailable");
                break;
        }
    
    }
    
    // Called if this device receives a request for a connection
    // This should only happen on the Server device
    -(void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID {
        NSLog(@"Received Connection Request From %@", peerID);
    
    // Accept the connection request from the peer
        [session acceptConnectionFromPeer:peerID error:nil];
    }
    
    - (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context {
        NSLog(@"Received Data");   
    }
    
    -(void)session:(GKSession *)session didFailWithError:(NSError *)error {
        NSLog(@"Session Failed: %@", error);
    }
    
    
    // Connected to a UIButton
    -(IBAction)sendData {
        NSLog(@"Sending Data ...");   
    }
    
    // Connected to a UIButton
    -(IBAction)beginConnection {
    
        Globals *globals = [Globals shareData];
    
    // Set this up as a server
        if (isHost) {
            GKSession *session = [[GKSession alloc] initWithSessionID:@"" displayName:@"Server" sessionMode:GKSessionModeServer];
            session.delegate = self;
            session.available = YES;       
            NSLog(@"Setting Server Session Peer:%@",  session.peerID);
            globals.localSession = session;
        } 
    
    // or set it up as a client
    else {
            GKSession *session = [[GKSession alloc] initWithSessionID:@"" displayName:nil sessionMode:GKSessionModeClient];
            session.delegate = self;
            session.available = YES;
            NSLog(@"Setting CLIENT Session Peer:%@", session.peerID);
            globals.localSession = session;
        }
    
    }
    
    
    ... Dealloc, etc...
    
    @end
    

    【讨论】:

    • 嗨,克里斯,我希望为 iOS 设备实现客户端服务器模型。我没有找到太多关于这方面的信息,你能建议我一些我可以使用的指针或资源吗?
    • @SumitLonkar 这是我为此写的一篇文章 (stackoverflow.com/a/12738287/1079207)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2015-07-13
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多