基本的に私は2つのスレッドを実行しています..1つはネットワーク経由で音楽をブロードキャストします(ブロードキャスターと呼びましょう)..もう1つはクライアントと通信して、ブロードキャストを開始するタイミング、音楽を再生するタイミングなどを認識します..(メインで実行)
ブロードキャスト スレッドは、サーバーがクライアントと通信している間も実行を続けます。ブロードキャスター スレッドを一時停止する必要があるのは 1 つの部分だけです。それは、クライアントにパケットを送信して音楽の再生を開始するときです (つまり、サーバーとクライアントの両方が同期して再生されます)。
私はほとんどすべてを使用しました (つまり、NSLocks、pthread_mutex_t と pthread_cond_t、スレッド スリープなど)。しかし、私はこのシナリオで実行し続けます。
基本的に、ブロードキャスター スレッドをロックアウトすることに成功しましたが、クロック設定が異なるように見えるコマンドで常に忍び寄ります。
ログに注意してください。
12:02:59.288 Snap[30700:7a0f] broadcaster--> sending packet number 69 to all peers
12:02:59.294 Snap[30700:7a0f] broadcaster--> going through packets loop
12:02:59.306 Snap[30700:707] communicator--> SERVER: WILL LOCK BROADCASTING
12:02:59.312 Snap[30700:707] communicator--> we are inside serverReceivedPacket
12:02:59.314 Snap[30700:707] communicator--> SERVER: JUST RECEIVED A PRIMED PACKET!
12:02:59.316 Snap[30700:707]communicator--> we are inside allPlayersArePrimed and we got 2 players
12:02:59.318 Snap[30700:707] communicator--> CLIENT: players are primed!
12:02:59.320 Snap[30700:707] communicator--> all players are primed now!.. pausing broadcast
12:02:59.322 Snap[30700:707] communicator--> will fire music player
12:02:59.311 Snap[30700:7a0f] broadcaster--> sending packet number 70 to all peers
12:02:59.335 Snap[30700:707] communicator--> SERVER: about to play [UNLOCK]
12:02:59.452 Snap[30700:7a0f] broadcaster--> going through packets loop
12:02:59.454 Snap[30700:7a0f] broadcaster--> sending packet number 71 to all peers
私の問題は、具体的には次の行にあります。
12:02:59.311 Snap[30700:7a0f] broadcaster--> sending packet number 70 to all peers
ブロードキャスター スレッド ログをたどると..最後のログ ステートメントが 12:02:59.288 で停止したことがわかります。その後、ロックアウトされました..しかし、コミュニケーターがロックを解除する前に..ブロードキャスターは 12 時にコマンドを投入しました:02:59.311.. それはコミュニケーター コマンドの後に来ましたが、それは時間的に後でした!
私はこのシナリオが何度も繰り返されるのを見てきました..それに対処する方法がわかりませんか?
コードの一部を次に示します。
コミュニケーターとブロードキャスターの両方で共有されるインスタンス変数:
@implementation Game
{
...
NSLock *broadcastLock;
}
コミュニケーター:
case PacketTypeClientPrimed:
{
player.isPrimed = true;
if (_state == GameStateWaitingForPrimed && [self allPlayersArePrimed])
{
[Logger Log:@"SERVER: WILL LOCK BROADCASTING"];
broadcastLock = [[NSLock alloc] init];
[broadcastLock lock];
_broadCastState = BroadCastStatePaused;
[hostViewController.musicPlayer skipToBeginning];
Packet *packet = [Packet packetWithType:PacketTypePlayMusicNow];
NSError *error;
NSLog(@"all players are primed now!.. pausing broadcast ");
[_session sendDataToAllPeers:[packet data] withDataMode:GKSendDataUnreliable error:&error];
NSLog(@"will fire music player");
[self performSelector:@selector(startMusic:) withObject:hostViewController.musicPlayer afterDelay:0.01];
_state = GameStatePlayBackCommenced;
}
}
....
-(void)startMusic:(MPMusicPlayerController *)player
{
NSLog(@"SERVER: about to play [UNLOCK]");
[player play];
_broadCastState = BroadCastStateInProgress;
[broadcastLock unlock];
}
放送局:
-(void)broadcastSample
{
[broadcastLock lock];
CMSampleBufferRef sample;
sample = [readerOutputcopyNextSampleBuffer];
....
for (int i = 0; i < inNumberPackets; ++i)
{
// ..
// setup audio packet
// ..
if ((packetSpaceRemaining < (dataSize + AUDIO_STREAM_PACK_DESC_SIZE)) ||
(packetDescrSpaceRemaining < AUDIO_STREAM_PACK_DESC_SIZE))
{
if (![self encapsulateAndShipPacket:packet packetDescriptions:packetDescriptions packetID:assetOnAirID])
break;
}
}
[broadcastLock unlock];
}