Skip to content

rabovik/RoUTP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reliable-over-Unreliable Transport Protocol

RoUTP is an Objective-C implementation of a simple Reliable-over-Unreliable Transport Protocol. Its primary goal is a workaround for «GKMatch GKMatchSendDataReliable packet loss bug» in Apple Game Center (see SO question & confirming example). But generally it may be used over any other unreliable protocol.

How it works

RoUTP acts as an additional transport layer between your app and unreliable transport. It saves all sent messages until acknowledgement for each received, resends lost and buffers received messages in case of broken sequence. Technically the sender numbers all sent messages and the receiver regularly sends positive selective acknowledgments.

Integration

Here is an example of using RoUTP in 2-player Game Center game. Suppose the code looks like

@interface MyController : UIViewController <GKMatchDelegate>
@property (nonatomic,strong) GKMatch *gkMatch;
@end

@implementation MyController
-(void)sendData:(NSData *)data{
    NSError *error;
    [self.gkMatch sendDataToAllPlayers:data
                          withDataMode:GKMatchSendDataReliable
                                 error:&error];
    //
}
-(void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID{
    [self doSomethingWithReceivedData:data];
}
@end

Let's add RoUTP

// 1. Import ROUSession.h header
#import "ROUSession.h"
@interface MyController : UIViewController <GKMatchDelegate,
					    ROUSessionDelegate> // 2. implement its delegate
@property (nonatomic,strong) GKMatch *gkMatch;
@property (nonatomic,strong) ROUSession *rouSession; // 3. add ROUSession property
@end

@implementation MyController
-(void)startGame{
    // 4. Make a ROUSession instance and set its delegate
    self.rouSession = [ROUSession new];
    self.rouSession.delegate = self;
}
-(void)sendData:(NSData *)data{
    // 5. Send data to ROUSession instead of GKMatch
    [self.rouSession sendData:data];
}
-(void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID{
    // 6. Send data from GKMatch to ROUSession
    [self.rouSession receiveData:data];
}
-(void)session:(ROUSession *)session preparedDataForSending:(NSData *)data{
    // 7. Send prepared data from ROUSession to GKMatch
    NSError *error;
    [self.gkMatch sendDataToAllPlayers:data
                          withDataMode:GKMatchSendDataUnreliable // we can use unreliable mode now
                                 error:&error];
    //
}
-(void)session:(ROUSession *)session receivedData:(NSData *)data{
    // 8. Process ready data from ROUSession
    [self doSomethingWithReceivedData:data];
}
-(void)endGame{
    // 9. Clean delegate and release session when it is no more needed.
    self.rouSession.delegate = nil;
    self.rouSession = nil;
}
@end

Requirements

  • iOS 5.0 and later
  • ARC

License

MIT License.

About

Reliable-over-Unreliable Transport Protocol for Apple Game Center Multiplayer

Resources

License

Stars

Watchers

Forks

Packages

No packages published