// add a new batch. // returns true if valid. // returns false if not, in which case the connection should be disconnected. public bool AddBatch(ArraySegment <byte> batch) { // IMPORTANT: ArraySegment is only valid until returning. we copy it! // // NOTE: it's not possible to create empty ArraySegments, so we // don't need to check against that. // make sure we have at least 8 bytes to read for tick timestamp if (batch.Count < Batcher.HeaderSize) { return(false); } // put into a (pooled) writer // -> WriteBytes instead of WriteSegment because the latter // would add a size header. we want to write directly. // -> will be returned to pool when sending! NetworkWriterPooled writer = NetworkWriterPool.Get(); writer.WriteBytes(batch.Array, batch.Offset, batch.Count); // first batch? then point reader there if (batches.Count == 0) { StartReadingBatch(writer); } // add batch batches.Enqueue(writer); //Debug.Log($"Adding Batch {BitConverter.ToString(batch.Array, batch.Offset, batch.Count)} => batches={batches.Count} reader={reader}"); return(true); }
// add a message for batching // we allow any sized messages. // caller needs to make sure they are within max packet size. public void AddMessage(ArraySegment <byte> message, double timeStamp) { // when appending to a batch in progress, check final size. // if it expands beyond threshold, then we should finalize it first. // => less than or exactly threshold is fine. // GetBatch() will finalize it. // => see unit tests. if (batch != null && batch.Position + message.Count > threshold) { batches.Enqueue(batch); batch = null; } // initialize a new batch if necessary if (batch == null) { // borrow from pool. we return it in GetBatch. batch = NetworkWriterPool.Get(); // write timestamp first. // -> double precision for accuracy over long periods of time // -> batches are per-frame, it doesn't matter which message's // timestamp we use. batch.WriteDouble(timeStamp); } // add serialization to current batch. even if > threshold. // -> we do allow > threshold sized messages as single batch // -> WriteBytes instead of WriteSegment because the latter // would add a size header. we want to write directly. batch.WriteBytes(message.Array, message.Offset, message.Count); }
// add a message for batching // we allow any sized messages. // caller needs to make sure they are within max packet size. public void AddMessage(ArraySegment <byte> message) { // put into a (pooled) writer // -> WriteBytes instead of WriteSegment because the latter // would add a size header. we want to write directly. // -> will be returned to pool when making the batch! // IMPORTANT: NOT adding a size header / msg saves LOTS of bandwidth NetworkWriterPooled writer = NetworkWriterPool.Get(); writer.WriteBytes(message.Array, message.Offset, message.Count); messages.Enqueue(writer); }
// Send stage two: serialized NetworkMessage as ArraySegment<byte> internal override void Send(ArraySegment <byte> segment, int channelId = Channels.Reliable) { // get a writer to copy the message into since the segment is only // valid until returning. // => pooled writer will be returned to pool when dequeuing. // => WriteBytes instead of WriteArraySegment because the latter // includes a 4 bytes header. we just want to write raw. //Debug.Log($"Enqueue {BitConverter.ToString(segment.Array, segment.Offset, segment.Count)}"); NetworkWriterPooled writer = NetworkWriterPool.Get(); writer.WriteBytes(segment.Array, segment.Offset, segment.Count); connectionToServer.queue.Enqueue(writer); }