Öbekleme Kanalı
ChunkingChannel örneği, özel bir protokolün veya katmanlı kanalın rastgele büyük iletileri öbekleme ve atlama işlemi yapmak için nasıl kullanılabileceğini gösterir.
Windows Communication Foundation (WCF) kullanarak büyük iletiler gönderirken, genellikle bu iletileri arabelleğe almak için kullanılan bellek miktarını sınırlamak istenir. Olası çözümlerden biri ileti gövdesinin akışını yapmaktır (verilerin büyük bir kısmının gövdede olduğu varsayılarak). Ancak bazı protokoller iletinin tamamını arabelleğe almayı gerektirir. Güvenilir mesajlaşma ve güvenlik bu tür iki örnektir. Başka bir olası çözüm, büyük iletiyi öbek adı verilen daha küçük iletilere bölmek, bu öbekleri birer birer bir öbek göndermek ve büyük iletiyi alıcı tarafında yeniden oluşturmaktır. Uygulamanın kendisi bu öbekleme ve öbek kaldırma işlemini gerçekleştirebilir veya bunu yapmak için özel bir kanal kullanabilir.
Öbekleme her zaman yalnızca gönderilecek iletinin tamamı oluşturulduktan sonra kullanılmalıdır. Öbekleme kanalı her zaman bir güvenlik kanalının ve güvenilir bir oturum kanalının altına katmanlanmalıdır.
Not
Bu örnek için kurulum yordamı ve derleme yönergeleri bu konunun sonunda yer alır.
Kanal Varsayımlarını ve Sınırlamalarını Öbekleme
İleti Yapısı
Öbekleme kanalı, iletilerin öbeklenmesi için aşağıdaki ileti yapısını varsayar:
<soap:Envelope>
<!-- headers -->
<soap:Body>
<operationElement>
<paramElement>data to be chunked</paramElement>
</operationElement>
</soap:Body>
</soap:Envelope>
ServiceModel kullanılırken, 1 giriş parametresine sahip sözleşme işlemleri, giriş iletisi için bu ileti şekliyle uyumlu olur. Benzer şekilde, 1 çıkış parametresi veya dönüş değeri olan sözleşme işlemleri, çıkış iletisi için bu ileti şekliyle uyumludur. Aşağıda bu tür işlemlere örnekler verilmiştir:
[ServiceContract]
interface ITestService
{
[OperationContract]
Stream EchoStream(Stream stream);
[OperationContract]
Stream DownloadStream();
[OperationContract(IsOneWay = true)]
void UploadStream(Stream stream);
}
Oturumlar
Öbekleme kanalı, iletilerin sıralı tesliminde (öbekler) tam olarak bir kez teslim edilmesi gerekir. Bu, temel alınan kanal yığınının oturumlu olması gerektiği anlamına gelir. Oturumlar aktarım (örneğin, TCP aktarımı) veya oturumlu bir protokol kanalı (örneğin ReliableSession kanalı) tarafından sağlanabilir.
Zaman Uyumsuz Gönderme ve Alma
Zaman uyumsuz gönderme ve alma yöntemleri, öbekleme kanalı örneğinin bu sürümünde uygulanmaz.
Öbekleme Protokolü
Öbekleme kanalı, bir öbek dizisinin başlangıcını ve sonunu ve her öbek sırasını gösteren bir protokol tanımlar. Aşağıdaki üç örnek ileti, başlangıç, öbek ve bitiş iletilerini, her birinin önemli yönlerini açıklayan açıklamalarla gösterir.
İletiyi Başlat
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<!--Original message action is replaced with a chunking-specific action. -->
<a:Action s:mustUnderstand="1">http://samples.microsoft.com/chunkingAction</a:Action>
<!--
Original message is assigned a unique id that is transmitted
in a MessageId header. Note that this is different from the WS-Addressing MessageId header.
-->
<MessageId s:mustUnderstand="1" xmlns="http://samples.microsoft.com/chunking">
53f183ee-04aa-44a0-b8d3-e45224563109
</MessageId>
<!--
ChunkingStart header signals the start of a chunked message.
-->
<ChunkingStart s:mustUnderstand="1" i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://samples.microsoft.com/chunking" />
<!--
Original message action is transmitted in OriginalAction.
This is required to re-create the original message on the other side.
-->
<OriginalAction xmlns="http://samples.microsoft.com/chunking">
http://tempuri.org/ITestService/EchoStream
</OriginalAction>
<!--
All original message headers are included here.
-->
</s:Header>
<s:Body>
<!--
Chunking assumes this structure of Body content:
<element>
<childelement>large data to be chunked<childelement>
</element>
The start message contains just <element> and <childelement> without
the data to be chunked.
-->
<EchoStream xmlns="http://tempuri.org/">
<stream />
</EchoStream>
</s:Body>
</s:Envelope>
Öbek İletisi
<s:Envelope
xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<!--
All chunking protocol messages have this action.
-->
<a:Action s:mustUnderstand="1">
http://samples.microsoft.com/chunkingAction
</a:Action>
<!--
Same as MessageId in the start message. The GUID indicates which original message this chunk belongs to.
-->
<MessageId s:mustUnderstand="1"
xmlns="http://samples.microsoft.com/chunking">
53f183ee-04aa-44a0-b8d3-e45224563109
</MessageId>
<!--
The sequence number of the chunk.
This number restarts at 1 with each new sequence of chunks.
-->
<ChunkNumber s:mustUnderstand="1"
xmlns="http://samples.microsoft.com/chunking">
1096
</ChunkNumber>
</s:Header>
<s:Body>
<!--
The chunked data is wrapped in a chunk element.
The encoding of this data (and the entire message)
depends on the encoder used. The chunking channel does not mandate an encoding.
-->
<chunk xmlns="http://samples.microsoft.com/chunking">
kfSr2QcBlkHTvQ==
</chunk>
</s:Body>
</s:Envelope>
İletiyi Sonlandır
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">
http://samples.microsoft.com/chunkingAction
</a:Action>
<!--
Same as MessageId in the start message. The GUID indicates which original message this chunk belongs to.
-->
<MessageId s:mustUnderstand="1"
xmlns="http://samples.microsoft.com/chunking">
53f183ee-04aa-44a0-b8d3-e45224563109
</MessageId>
<!--
ChunkingEnd header signals the end of a chunk sequence.
-->
<ChunkingEnd s:mustUnderstand="1" i:nil="true"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://samples.microsoft.com/chunking" />
<!--
ChunkingEnd messages have a sequence number.
-->
<ChunkNumber s:mustUnderstand="1"
xmlns="http://samples.microsoft.com/chunking">
79
</ChunkNumber>
</s:Header>
<s:Body>
<!--
The ChunkingEnd message has the same <element><childelement> structure
as the ChunkingStart message.
-->
<EchoStream xmlns="http://tempuri.org/">
<stream />
</EchoStream>
</s:Body>
</s:Envelope>
Kanal Mimarisi öbekleme
Öbekleme kanalı, yüksek düzeyde tipik kanal mimarisini izleyen bir IDuplexSessionChannel
kanaldır. ChunkingBindingElement
ve oluşturabilen ChunkingChannelFactory
bir ChunkingChannelListener
vardır. , ChunkingChannelFactory
istendiğinde örneklerini ChunkingChannel
oluşturur. , ChunkingChannelListener
yeni bir iç kanalın ChunkingChannel
kabul edildiği örnekleri oluşturur. İleti ChunkingChannel
göndermek ve almak kendi sorumluluğundadır.
Bir sonraki düzeyde, ChunkingChannel
öbekleme protokollerini uygulamak için birkaç bileşene dayanır. Gönderme tarafında kanal, gerçek öbekleme işlemini yerine getiren adlı ChunkingWriter
özel XmlDictionaryWriter bir ad kullanır. ChunkingWriter
öbekleri göndermek için doğrudan iç kanalı kullanır. Özel XmlDictionaryWriter
kullanmak, özgün iletinin büyük gövdesi yazılırken öbek göndermemizi sağlar. Bu, özgün iletinin tamamını arabelleğe almadığımız anlamına gelir.
Alma tarafında, ChunkingChannel
iletileri iç kanaldan çeker ve gelen öbeklerden özgün iletiyi yeniden oluşturan adlı ChunkingReader
bir özel XmlDictionaryReader iletiye iletir. ChunkingChannel
bunu ChunkingReader
adlı ChunkingMessage
özel Message
bir uygulamada sarmalar ve bu iletiyi yukarıdaki katmana döndürür. bu ve ChunkingMessage
bileşimiChunkingReader
, özgün ileti gövdesinin tamamını arabelleğe almak zorunda kalmak yerine yukarıdaki katman tarafından okunmakta olan özgün ileti gövdesinin öbeklerini kaldırmamıza olanak tanır. ChunkingReader
, gelen öbekleri en fazla yapılandırılabilir arabelleğe alınmış öbek sayısına kadar arabelleğe aldığı bir kuyruğa sahiptir. Bu üst sınıra ulaşıldığında, okuyucu iletilerin kuyruktan yukarıdaki katman tarafından boşaltılması için (yani, yalnızca özgün ileti gövdesinden okuyarak) veya maksimum alma zaman aşımına ulaşılana kadar bekler.
Programlama Modelini Öbekleme
Hizmet geliştiricileri, özniteliği sözleşmedeki işlemlere uygulayarak hangi iletilerin ChunkingBehavior
öbekleneceğini belirtebilir. özniteliği, geliştiricinin öbeklemenin giriş iletisine mi, çıkış iletisine mi yoksa her ikisine mi uygulanacağını belirtmesine olanak tanıyan bir AppliesTo
özellik sunar. Aşağıdaki örnekte özniteliğin kullanımı gösterilmektedir ChunkingBehavior
:
[ServiceContract]
interface ITestService
{
[OperationContract]
[ChunkingBehavior(ChunkingAppliesTo.Both)]
Stream EchoStream(Stream stream);
[OperationContract]
[ChunkingBehavior(ChunkingAppliesTo.OutMessage)]
Stream DownloadStream();
[OperationContract(IsOneWay=true)]
[ChunkingBehavior(ChunkingAppliesTo.InMessage)]
void UploadStream(Stream stream);
}
Bu programlama modelinden ChunkingBindingElement
, öbeklenecek iletileri tanımlayan eylem URI'lerinin listesini derler. Her giden iletinin eylemi, iletinin öbeklenmesi mi yoksa doğrudan gönderilmesi mi gerektiğini belirlemek için bu listeyle karşılaştırılır.
Gönderme İşlemi Uygulama
Yüksek düzeyde, Gönder işlemi önce giden iletinin öbeklenip öbeklenmemesi gerektiğini denetler ve değilse, iletiyi doğrudan iç kanalı kullanarak gönderir.
İletinin öbeklenmesi gerekiyorsa, Gönder yeni ChunkingWriter
bir oluşturur ve giden iletide bunu ChunkingWriter
ileten çağrılarWriteBodyContents
. ardından ChunkingWriter
, ileti öbeklemesi yapar (özgün ileti üst bilgilerini başlangıç öbek iletisine kopyalama dahil) ve iç kanalı kullanarak öbekler gönderir.
Dikkate değer birkaç ayrıntı:
öğesinin açıldığından emin olmak için ilk çağrıları
ThrowIfDisposedOrNotOpened
CommunicationState
gönderin.Gönderme eşitlenir, böylece her oturum için aynı anda yalnızca bir ileti gönderilebilir. Öbeklenmiş bir
ManualResetEvent
ileti gönderilirken sıfırlanan adlı bir adsendingDone
vardır. Uç öbek iletisi gönderildikten sonra bu olay ayarlanır. Send yöntemi, giden iletiyi göndermeye çalışmadan önce bu olayın ayarlanmasını bekler.Gönder, gönderirken eşitlenmiş durum değişikliklerini önlemek için öğesini kilitler
CommunicationObject.ThisLock
. CommunicationObject Durumlar ve durum makinesi hakkında CommunicationObject daha fazla bilgi için belgelere bakın.Gönder'e geçirilen zaman aşımı, tüm öbeklerin gönderilmesini içeren gönderme işleminin tamamı için zaman aşımı olarak kullanılır.
Özgün ileti gövdesinin tamamını arabelleğe almaktan kaçınmak için özel XmlDictionaryWriter tasarım seçildi. Eğer cesedin tamamını kullanarak
message.GetReaderAtBodyContents
bir ceset alırsak XmlDictionaryReader arabelleğe alınırdı. Bunun yerine, öğesinemessage.WriteBodyContents
geçirilen bir özel XmlDictionaryWriter öğemiz var. İleti yazıcıda WriteBase64'i çağırdıkça, yazıcı öbekleri iletilere paketler ve iç kanalı kullanarak gönderir. Öbek gönderilene kadar WriteBase64 blokları.
Alma İşlemi Uygulama
Yüksek düzeyde, Receive işlemi önce gelen iletinin olmadığını null
ve eyleminin ChunkingAction
olduğunu denetler. Her iki ölçüte de uymazsa, ileti Alış'tan değiştirilmeden döndürülür. Aksi takdirde, Receive yeni ChunkingReader
bir ve çevresinde sarmalanmış yeni ChunkingMessage
bir oluşturur (çağırarak GetNewChunkingMessage
). Bu yeni ChunkingMessage
öğesini döndürmeden önce Receive, bir ReceiveChunkLoop
döngüde çağrısı innerChannel.Receive
yapan ve öbekleri son öbek iletisi alınana veya alma zaman aşımına ulaşana ChunkingReader
kadar öğesine teslim eden bir iş parçacığı havuzu iş parçacığı kullanır.
Dikkate değer birkaç ayrıntı:
Gönder gibi, Aç olduğundan emin olmak için ilk çağrıları
ThrowIfDisposedOrNotOpened
CommunicationState
alın.Aynı anda oturumdan yalnızca bir ileti alınabilmesi için alma da eşitlenir. Bu özellikle önemlidir çünkü bir başlangıç öbek iletisi alındıktan sonra, bir son öbek iletisi alınana kadar sonraki tüm alınan iletilerin bu yeni öbek dizisi içinde öbekler olması beklenir. Alma, öbekleri kaldırılmakta olan iletiye ait tüm öbekler alınana kadar iç kanaldan iletileri çekemez. Bunu gerçekleştirmek için, Receive adlı
currentMessageCompleted
birManualResetEvent
kullanır. Bu, bitiş öbek iletisi alındığında ayarlanır ve yeni bir başlangıç öbek iletisi alındığında sıfırlanır.Gönder'in aksine Alma, alma sırasında eşitlenmiş durum geçişlerini engellemez. Örneğin, Kapat alınırken çağrılabilir ve özgün iletinin bekleyen alınması tamamlanana veya belirtilen zaman aşımı değerine ulaşılana kadar bekler.
Alma işlemine geçirilen zaman aşımı, tüm öbekleri almayı da içeren alma işleminin tamamı için zaman aşımı olarak kullanılır.
İletiyi kullanan katman, ileti gövdesini gelen öbek iletilerinin hızından daha düşük bir hızda tüketiyorsa,
ChunkingReader
bu gelen öbekleri tarafındanChunkingBindingElement.MaxBufferedChunks
belirtilen sınıra kadar arabelleğe alır. Bu sınıra ulaşıldıktan sonra, arabelleğe alınan bir öbek tüketilene veya alma zaman aşımına ulaşılana kadar alt katmandan başka öbek çekilmez.
CommunicationObject Geçersiz Kılmaları
OnOpen
OnOpen
iç kanalı açmak için aramalar innerChannel.Open
.
OnClose
OnClose
önce beklemede ReceiveChunkLoop
olanın durması için sinyal vermek için öğesini ayarlar.stopReceive
true
Ardından durdurulduğunda ayarlanan öğesini bekler receiveStopped
ManualResetEvent.ReceiveChunkLoop
ReceiveChunkLoop
Belirtilen zaman aşımı içinde durduğunu varsayarsak, OnClose
kalan zaman aşımıyla birlikte çağrılarinnerChannel.Close
.
OnAbort
OnAbort
iç kanalı durdurmak için çağrılar innerChannel.Abort
. Bekleyen ReceiveChunkLoop
bir çağrı varsa, bekleyen innerChannel.Receive
çağrıdan bir özel durum alır.
OnFaulted
ChunkingChannel
kanal hatalı olduğunda özel davranış gerektirmez, bu nedenle OnFaulted
geçersiz kılınmaz.
Channel Factory Uygulama
, ChunkingChannelFactory
ve örneklerinin oluşturulmasından ChunkingDuplexSessionChannel
ve durum geçişlerinin iç kanal fabrikasına basamaklanmasından sorumludur.
OnCreateChannel
iç kanal oluşturmak IDuplexSessionChannel
için iç kanal fabrikasını kullanır. Ardından, bu iç kanala, öbeklenecek ileti eylemlerinin listesi ve alma sırasında arabelleğe alınacak en fazla öbek sayısıyla birlikte yeni ChunkingDuplexSessionChannel
bir geçiş oluşturur. Öbeklenecek ileti eylemlerinin listesi ve arabelleğe alınacak en fazla öbek sayısı, oluşturucusunda geçirilen ChunkingChannelFactory
iki parametredir. üzerindeki ChunkingBindingElement
bölümünde bu değerlerin nereden geldiği açıklanmaktadır.
OnOpen
, OnClose
OnAbort
ve zaman uyumsuz eşdeğerleri, iç kanal fabrikasında ilgili durum geçiş yöntemini çağırır.
Kanal Dinleyicisi Uygulama
ChunkingChannelListener
, bir iç kanal dinleyicisinin etrafındaki sarmalayıcıdır. Ana işlevi, bu iç kanal dinleyicisine yapılan temsilci çağrılarının yanı sıra, iç kanal dinleyicisinden kabul edilen kanalların çevresinde yenileri ChunkingDuplexSessionChannels
kaydırmaktır. Bu işlem ve OnEndAcceptChannel
içinde OnAcceptChannel
yapılır. Yeni oluşturulan ChunkingDuplexSessionChannel
, daha önce açıklanan diğer parametrelerle birlikte iç kanala geçirilir.
Bağlama Öğesini ve Bağlamayı Uygulama
ChunkingBindingElement
ve ChunkingChannelListener
oluşturmakla ChunkingChannelFactory
sorumludur. , ChunkingBindingElement
T ve CanBuildChannelListener
<> T içindeki CanBuildChannelFactory
<T'nin> türünde IDuplexSessionChannel
olup olmadığını (öbekleme kanalı tarafından desteklenen tek kanal) ve bağlamadaki diğer bağlama öğelerinin bu kanal türünü destekleyip desteklemediğini denetler.
BuildChannelFactory
<T> önce istenen kanal türünün derlenip derlenebileceğini denetler ve ardından öbeklenecek ileti eylemlerinin listesini alır. Daha fazla bilgi için aşağıdaki bölüme bakın. Ardından iç kanal fabrikasını (öğesinden context.BuildInnerChannelFactory<IDuplexSessionChannel>
döndürüldükçe) ileti eylemleri listesini ve arabelleğe alınacak en fazla öbek sayısını geçirerek yeni ChunkingChannelFactory
bir oluşturur. Öbek sayısı üst sınırı, tarafından ChunkingBindingElement
kullanıma sunulan adlı MaxBufferedChunks
bir özellikten gelir.
BuildChannelListener<T>
, iç kanal dinleyicisini oluşturmak ChunkingChannelListener
ve geçirmek için benzer bir uygulamaya sahiptir.
Bu örnekte adlı TcpChunkingBinding
bir örnek bağlama vardır. Bu bağlama iki bağlama öğesinden oluşur: TcpTransportBindingElement
ve ChunkingBindingElement
. Bağlama, özelliğini kullanıma açmanın MaxBufferedChunks
yanı sıra gibi MaxReceivedMessageSize
bazı TcpTransportBindingElement
özellikleri de ayarlar (üst bilgiler için + 100 KB bayt olarak ayarlar ChunkingUtils.ChunkSize
).
TcpChunkingBinding
ayrıca yalnızca zaman uyumlu Alma çağrılarının IBindingRuntimePreferences
uygulandığını belirten yönteminden ReceiveSynchronously
true uygular ve döndürür.
Öbek alınacak iletileri belirleme
Öbekleme kanalı yalnızca özniteliği aracılığıyla ChunkingBehavior
tanımlanan iletileri öbekler. ChunkingBehavior
sınıfı IOperationBehavior
yöntemini çağırarak AddBindingParameter
uygular ve uygulanır. Bu yöntemdeChunkingBehavior
, hangi iletilerin öbeklenmesi gerektiğini belirlemek için özelliğinin AppliesTo
(InMessage
OutMessage
veya her ikisinin) değerini inceler. Ardından bu iletilerin her birinin eylemini alır (üzerindeki OperationDescription
İletiler koleksiyonundan) ve bir örneğinin içinde yer alan dize koleksiyonuna ChunkingBindingParameter
ekler. Ardından bunu ChunkingBindingParameter
sağlanan BindingParameterCollection
öğesine ekler.
Bu BindingParameterCollection
bağlama öğesi kanal fabrikasını BindingContext
veya kanal dinleyicisini oluştururken bağlamadaki her bağlama öğesine içinde geçirilir. 'ChunkingBindingElement
nin uygulaması BuildChannelFactory<T>
ve BuildChannelListener<T>
bunu ChunkingBindingParameter
içinden BindingParameterCollection
çekinBindingContext'
. içinde ChunkingBindingParameter
yer alan eylemlerin koleksiyonu daha sonra veya ChunkingChannelListener
öğesine geçirilir ChunkingChannelFactory
ve bu da bunu öğesine ChunkingDuplexSessionChannel
geçirir.
Örneği Çalıştırma
Örneği ayarlamak, derlemek ve çalıştırmak için
Aşağıdaki komutu kullanarak ASP.NET 4.0'ı yükleyin.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
Windows Communication Foundation Örnekleri için Tek Seferlik Kurulum Yordamı'nı gerçekleştirdiğinizden emin olun.
Çözümü oluşturmak için Windows Communication Foundation Örnekleri Oluşturma başlığındaki yönergeleri izleyin.
Örneği tek veya makineler arası bir yapılandırmada çalıştırmak için Windows Communication Foundation Örneklerini Çalıştırma başlığındaki yönergeleri izleyin.
önce Service.exe çalıştırın, ardından Client.exe çalıştırın ve çıkış için her iki konsol penceresini de izleyin.
Örnek çalıştırılırken aşağıdaki çıkış beklenir.
İstemci:
Press enter when service is available
> Sent chunk 1 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 2 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 3 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 4 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 5 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 6 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 7 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 8 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 9 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 10 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 1 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 2 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 3 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 4 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 5 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 6 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 7 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 8 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 9 of message 5b226ad5-c088-4988-b737-6a565e0563dd
< Received chunk 10 of message 5b226ad5-c088-4988-b737-6a565e0563dd
Sunucu:
Service started, press enter to exit
< Received chunk 1 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 2 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 3 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 4 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 5 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 6 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 7 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 8 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 9 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
< Received chunk 10 of message 867c1fd1-d39e-4be1-bc7b-32066d7ced10
> Sent chunk 1 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 2 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 3 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 4 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 5 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 6 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 7 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 8 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 9 of message 5b226ad5-c088-4988-b737-6a565e0563dd
> Sent chunk 10 of message 5b226ad5-c088-4988-b737-6a565e0563dd