//TODO できればScene単位でパケットをまとめて、type(1byte) sceneHash(4byte)の5byteのデータを削減したい private void CreateRpcPacket(ref DataStreamWriter writer, ref DataStreamWriter rpcPacket, byte componentIndex, byte methodId) { unsafe { byte *dataPtr = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(rpcPacket); writer.Write((byte)BuiltInPacket.Type.BehaviourRpc); writer.Write(sceneHash); writer.Write(netId); writer.Write(componentIndex); writer.Write(methodId); writer.WriteBytes(dataPtr, rpcPacket.Length); } }
protected DataStreamWriter CreateSendPacket(DataStreamWriter data, QosType qos, ushort targetId, ushort senderId) { unsafe { byte * dataPtr = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(data); ushort dataLength = (ushort)data.Length; var writer = new DataStreamWriter(data.Length + 4, Allocator.Temp); writer.Write(targetId); writer.Write(senderId); writer.WriteBytes(dataPtr, data.Length); return(writer); } }
protected DataStreamWriter CreateSendPacket(DataStreamWriter data, QosType qos, NativeList <ushort> targetIdList, ushort senderId) { unsafe { byte * dataPtr = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(data); ushort dataLength = (ushort)data.Length; var writer = new DataStreamWriter(data.Length + 6 + targetIdList.Length * 2, Allocator.Temp); writer.Write(ushort.MaxValue - 1); writer.Write(senderId); writer.Write((ushort)targetIdList.Length); for (int i = 0; i < targetIdList.Length; i++) { writer.Write(targetIdList[i]); } writer.WriteBytes(dataPtr, data.Length); return(writer); } }
public void Execute() { DataStreamReader stream; NetworkEvent.Type cmd; //前フレームで解決できなかったbufferedからuncheckedに登録. if (!savedUncheckedReliableDataStream.IsCreated) { stream = new DataStreamReader(savedUncheckedReliableDataStream, 0, savedUncheckedReliableDataStream.Length); int offset = 0; while (offset < savedUncheckedReliableDataStream.Length) { var readerCtx = default(DataStreamReader.Context); ushort length = stream.ReadUShort(ref readerCtx); if (0 < length && length <= savedUncheckedReliableDataStream.Length - offset - 2) { uncheckedreliableStreams.Add( new DataStreamReader(savedUncheckedReliableDataStream, offset + 2, length)); offset += length + 2; } else { break; } } } while ((cmd = connection.PopEvent(driver, out stream)) != NetworkEvent.Type.Empty) { if (cmd == NetworkEvent.Type.Connect) { flags[(int)FlagDef.IsConnected] = 1; Debug.Log("Connect : " + connection.InternalId); } else if (cmd == NetworkEvent.Type.Disconnect) { flags[(int)FlagDef.IsDisconnected] = 1; Debug.Log("Disconnect : " + connection.InternalId); } else if (cmd == NetworkEvent.Type.Data) { if (!stream.IsCreated) { continue; } var readerCtx = default(DataStreamReader.Context); byte qosType = stream.ReadByte(ref readerCtx); ushort seqNum = stream.ReadUShort(ref readerCtx); ushort ackNum = stream.ReadUShort(ref readerCtx); //if (qosType != (byte)QosType.MeasureLatency) { // Debug.Log ("Recieve Data Len=" + stream.Length + ",QoS=" + qosType + ",Seq=" + seqNum + ",Ack=" + ackNum); //} //最初のregister packetはseqNumに bool isInitialUpdate = flags[(int)FlagDef.IsNotInitialUpdate] == 0; //ackNumの更新 if (seqNumbers[(int)SeqNumberDef.OtherAck] != ackNum) { seqNumbers[(int)SeqNumberDef.OtherAck] = ackNum; //Debug.Log ("update OtherAck = " + ackNum + " first=" + isInitialUpdate); } switch ((QosType)qosType) { case QosType.MeasureLatency: long currentUnixTime = System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long otherUnixTime = stream.ReadLong(ref readerCtx); seqNumbers[(int)SeqNumberDef.Latency] = (ushort)(currentUnixTime - otherUnixTime); break; case QosType.Unreliable: dataStreams.Add(stream); break; case QosType.Reliable: int seqNumberDiff = (int)seqNum - seqNumbers[(int)SeqNumberDef.OtherSeq]; if (!isInitialUpdate && seqNumberDiff > 1) { //Debug.Log ("Reliable seqNumberDiff > 1 recieve"); //順番が入れ替わってるからバッファに貯める if (seqNumberDiff - 2 < uncheckedreliableStreams.Length) { if (uncheckedreliableStreams[seqNumberDiff - 2].IsCreated) { uncheckedreliableStreams[seqNumberDiff - 2] = stream; } } else { uncheckedreliableStreams.Add(stream); } } else if (isInitialUpdate || (seqNumberDiff == 1 || seqNumberDiff == -ushort.MaxValue)) { flags[(int)FlagDef.IsNotInitialUpdate] = 1; //次の順のパケットなら確定する seqNumbers[(int)SeqNumberDef.OtherSeq] = seqNum; //Debug.Log ("update OtherSeq = " + seqNumbers[(int)SeqNumberDef.OtherSeq] + " first=" + isInitialUpdate); //AddChunksInDataStream (stream, ref readerCtx); dataStreams.Add(stream); //順番待ちのパケットを確定する while (uncheckedreliableStreams.Length != 0) { if (!uncheckedreliableStreams[0].IsCreated) { IncrementSequenceNumber(SeqNumberDef.OtherSeq); //Debug.Log ("update OtherSeq = " + seqNumbers[(int)SeqNumberDef.OtherSeq]); //AddChunksInDataStream (uncheckedreliableStreams[0], ref readerCtx); dataStreams.Add(uncheckedreliableStreams[0]); uncheckedreliableStreams.RemoveAtSwapBack(0); } else { break; } } } else { //受信済みのSeqNumのパケットなら無視 //Debug.Log ("Reliable same recieve"); } break; } } } //uncheckedreliableStreamsに残ったパケットはnetworkdriverから実態が消される前にコピーしておく unsafe { //uncheckedreliableStreamsはsavedUncheckedReliableDataStreamに実態を持つ場合があるので //直接savedUncheckedReliableDataStream書き込むと実態が消えてしまうのでtempまず書く tempUncheckedReliableDataStream.Clear(); for (int i = 0; i < uncheckedreliableStreams.Length; i++) { int dataLength = uncheckedreliableStreams[i].Length; if (tempUncheckedReliableDataStream.Capacity - tempUncheckedReliableDataStream.Length < dataLength + 2) { tempUncheckedReliableDataStream.Capacity *= 2; } byte *dataPtr = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(uncheckedreliableStreams[i]); tempUncheckedReliableDataStream.Write(dataLength); tempUncheckedReliableDataStream.WriteBytes(dataPtr, dataLength); } savedUncheckedReliableDataStream.Clear(); if (savedUncheckedReliableDataStream.Capacity < tempUncheckedReliableDataStream.Capacity) { savedUncheckedReliableDataStream.Capacity *= tempUncheckedReliableDataStream.Capacity; } savedUncheckedReliableDataStream.WriteBytes( tempUncheckedReliableDataStream.GetUnsafeReadOnlyPtr(), tempUncheckedReliableDataStream.Length); } //次に自分が送るパケットでどこまで受け取ったか伝える. seqNumbers[(int)SeqNumberDef.SelfAck] = seqNumbers[(int)SeqNumberDef.OtherSeq]; }