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.
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.
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
- iOS 5.0 and later
- ARC
MIT License.