Exemplo n.º 1
0
        // send a batch. internal so we can test it.
        internal void SendBatch(int channelId, Batch batch)
        {
            // get max batch size for this channel
            int max = Transport.activeTransport.GetMaxBatchSize(channelId);

            // we need a writer to merge queued messages into a batch
            using (PooledNetworkWriter writer = NetworkWriterPool.GetWriter())
            {
                // for each queued message
                while (batch.messages.Count > 0)
                {
                    // get it
                    PooledNetworkWriter message = batch.messages.Dequeue();
                    ArraySegment <byte> segment = message.ToArraySegment();

                    // IF adding to writer would end Up >= MTU then we should
                    // flush first. the goal is to always flush < MTU packets.
                    //
                    // IMPORTANT: if writer is empty and segment is > MTU
                    //            (which can happen for large max sized message)
                    //            then we would send an empty previous writer.
                    //            => don't do that.
                    //            => only send if not empty.
                    if (writer.Position > 0 &&
                        writer.Position + segment.Count >= max)
                    {
                        // flush & reset writer
                        Transport.activeTransport.ServerSend(connectionId, channelId, writer.ToArraySegment());
                        writer.SetLength(0);
                    }

                    // now add to writer in any case
                    // -> WriteBytes instead of WriteSegment because the latter
                    //    would add a size header. we want to write directly.
                    //
                    // NOTE: it's very possible that we add > MTU to writer if
                    //       message size is > MTU.
                    //       which is fine. next iteration will just flush it.
                    writer.WriteBytes(segment.Array, segment.Offset, segment.Count);

                    // return queued message to pool
                    NetworkWriterPool.Recycle(message);
                }

                // done iterating queued messages.
                // batch might still contain the last message.
                // send it.
                if (writer.Position > 0)
                {
                    Transport.activeTransport.ServerSend(connectionId, channelId, writer.ToArraySegment());
                    writer.SetLength(0);
                }
            }

            // reset send time for this channel's batch
            batch.lastSendTime = NetworkTime.time;
        }
        public static PooledNetworkWriter GetWriter()
        {
            if (pool.Count != 0)
            {
                PooledNetworkWriter writer = pool.Pop();
                // reset cached writer length and position
                writer.SetLength(0);
                return(writer);
            }

            return(new PooledNetworkWriter());
        }