以前のスタック オーバーフローの質問では、Akka ソケット サーバーを構築しているときに、私の方法の誤りを示すのに非常に役立ちました。実際に、次のフレーミングでメッセージを送信できる Akka ソケット クライアントがあります。
メッセージ長: 4 バイト メッセージ タイプ: 4 バイト メッセージ ペイロード: (長さ) バイト
メッセージの送信に使用している iOS コードは次のとおりです。
NSInputStream *inputStream;
NSOutputStream *outputStream;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"localhost", 9999, &readStream, &writeStream);
inputStream = (__bridge_transfer NSInputStream *)readStream;
outputStream = (__bridge_transfer NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
// [inputStream open];
[outputStream open];
NSLog(@"NSData raw zombie is %d bytes.", [rawZombie length]);
uint32_t length = (uint32_t)htonl([rawZombie length]);
uint32_t messageType = (uint32_t)htonl(1);
NSLog(@"Protobuf byte size %d", zombieSighting->ByteSize());
[outputStream write:(uint8_t *)&length maxLength:4];
[outputStream write:(uint8_t *)&messageType maxLength:4];
[outputStream write:(uint8_t *)[rawZombie bytes] maxLength:length];
[outputStream close];
「rawZombie」変数 (NSData *) は、次のメソッドから取得されます。
- (NSData *)getDataForZombie:(kotancode::ZombieSighting *)zombie {
std::string ps = zombie->SerializeAsString();
NSLog(@"raw zombie string:\n[%s]", ps.c_str());
return [NSData dataWithBytes:ps.c_str() length:ps.size()];
}
私が見ている症状は、iOS から送信されたメッセージを受信し、メッセージ タイプ (1) と同様に長さが正しく、本文が問題なく表示されることです。Scala protobufs を使用する Akka サーバーは、メッセージを逆シリアル化し、メッセージのすべての値を完全に出力します。問題は、そのメッセージを受け取った直後に、Akka サーバーが別のメッセージを受け取ったと見なすことです (明らかに、ストリームにさらにデータが入ってきました)。最後のデータは、iOS アプリを実行するたびに同じではありません。
たとえば、2 つの連続したメッセージ受信からのトレース出力を次に示します。
received message of length 45 and type 1
name:Kevin
lat: 41.007
long: 21.007
desc:This is a zombie
zombie type:FAST
received message of length 7 and type 4
received message of length 45 and type 1
name:Kevin
lat: 41.007
long: 21.007
desc:This is a zombie
zombie type:FAST
received message of length 164 and type 1544487554
つまり、Akka サーバーがメッセージの適切なデータを受信した直後に、ランダムな任意のがらくたも受信することがわかります。この余分な恣意的ながらくたなしでAkkaクライアントが適切に動作していることを考えると、protobufオブジェクトをNSStreamに書き込む方法に何か問題があると思います...誰かが私の愚かな間違いを見つけることができますか?ここで起こっています。