﻿
{"id":20567,"date":"2021-01-06T23:52:25","date_gmt":"2021-01-06T23:52:25","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=20567"},"modified":"2021-01-06T23:52:25","modified_gmt":"2021-01-06T23:52:25","slug":"grpc-bi-directional-streaming-yontemiyle-client-ve-server-iletisimi","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/grpc-bi-directional-streaming-yontemiyle-client-ve-server-iletisimi\/","title":{"rendered":"gRPC &#8211; Bi-directional Streaming Y\u00f6ntemiyle Client ve Server \u0130leti\u015fimi"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde, iki uygulama aras\u0131nda ileti\u015fimin gRPC \u00fczerinden Bi-directional y\u00f6ntemiyle nas\u0131l sa\u011fland\u0131\u011f\u0131n\u0131 pratikte inceliyor olaca\u011f\u0131z.<\/p>\n<p>\u0130lk olarak Bi-directional y\u00f6nteminin ne oldu\u011funu hat\u0131rlayarak ba\u015flayal\u0131m.<br \/>\n<div id=\"attachment_20395\" style=\"width: 391px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/gRPC-Nedir-Ne-Amacla-ve-Nasil-Kullanilir-5.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-20395\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/gRPC-Nedir-Ne-Amacla-ve-Nasil-Kullanilir-5.png\" alt=\"gRPC Nedir? Ne Ama\u00e7la ve Nas\u0131l Kullan\u0131l\u0131r?\" width=\"381\" height=\"193\" class=\"size-full wp-image-20395\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/gRPC-Nedir-Ne-Amacla-ve-Nasil-Kullanilir-5.png 381w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/gRPC-Nedir-Ne-Amacla-ve-Nasil-Kullanilir-5-300x152.png 300w\" sizes=\"auto, (max-width: 381px) 100vw, 381px\" \/><\/a><p id=\"caption-attachment-20395\" class=\"wp-caption-text\">Client\u2019\u0131n server\u2019a stream mesaj g\u00f6nderdi\u011fi ve server\u2019\u0131n stream response d\u00f6nd\u00fcrd\u00fc\u011f\u00fc RPC t\u00fcr\u00fcd\u00fcr. Yani hem client hem de server kar\u015f\u0131l\u0131kl\u0131 message streaming ger\u00e7ekle\u015ftirmektedir ve b\u00f6ylece birden \u00e7ok mesaj transferi sa\u011flanabilmektedir. bknz: Duplex messaging<\/p><\/div><\/p>\n<p>Bi-directional Streaming, \u00f6nceden ele ald\u0131\u011f\u0131m\u0131z <a href=\"https:\/\/www.gencayyildiz.com\/blog\/grpc-client-streaming-yontemiyle-client-ve-server-iletisimi\/\" rel=\"noopener noreferrer\" target=\"_blank\">Client Streaming<\/a> ile <a href=\"https:\/\/www.gencayyildiz.com\/blog\/grpc-server-streaming-yontemiyle-client-ve-server-iletisimi\/\" rel=\"noopener noreferrer\" target=\"_blank\">Server Streaming<\/a>&#8216;in kombine edilmi\u015f varyasyonu olarak \u00e7al\u0131\u015fmakta ve her iki uygulaman\u0131n birbirine stream data g\u00f6nderdi\u011fi bir yakla\u015f\u0131m sergilememizi sa\u011flamaktad\u0131r. \u015eimdi gelin, bu y\u00f6ntem ile bir client ve server \u00e7al\u0131\u015fmas\u0131 sergileyelim.<\/p>\n<h4 style=\"color:purple;\">Proto Dosyas\u0131<\/h4>\n<p>Client ve server olmak \u00fczere iki uygulama aras\u0131ndaki kontrat\u0131 a\u015fa\u011f\u0131daki <em>message.proto<\/em> dosyas\u0131 \u00fczerinden sa\u011flayaca\u011f\u0131z.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nsyntax = &quot;proto3&quot;;\r\noption csharp_namespace = &quot;gRPCExample&quot;;\r\npackage message;\r\n\r\nservice Message {\r\n  rpc GetMessage(stream MessageRequest) returns (stream MessageResponse);\r\n}\r\nmessage MessageRequest {\r\n  string message = 1;\r\n}\r\nmessage MessageResponse {\r\n  string message = 1;\r\n}\r\n<\/pre>\n<p>Yukar\u0131daki <em>message.proto<\/em> i\u00e7eri\u011fine g\u00f6z atarsan\u0131z e\u011fer i\u00e7erisinde &#8216;GetMessage&#8217; isimli fonksiyon bar\u0131nd\u0131ran &#8216;Message&#8217; isimli bir servis olu\u015fturulmaktad\u0131r. \u0130lgili fonksiyon yap\u0131lacak request neticesinde bir &#8216;MessageRequest&#8217; stream&#8217;i istemekte ve response olarak geriye &#8216;MessageResponse&#8217; stream&#8217;i d\u00f6nd\u00fcrmektedir. Yani g\u00f6nderilen birden fazla &#8216;MessageRequest&#8217; nesnesine kar\u015f\u0131l\u0131k yine birden fazla &#8216;MessageResponse&#8217; nesnesini cevap olarak g\u00f6ndermektedir.<\/p>\n<h4 style=\"color:purple;\">Server&#8217;da Message Service&#8217;i<\/h4>\n<p>Client&#8217;tan gelecek olan iste\u011fi server&#8217;da kar\u015f\u0131layacak olan &#8216;MessageService&#8217;i a\u015fa\u011f\u0131daki gibi tasarlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class MessageService : MessageBase\r\n    {\r\n        public async override Task GetMessage(IAsyncStreamReader&lt;MessageRequest&gt; requestStream, IServerStreamWriter&lt;MessageResponse&gt; responseStream, ServerCallContext context)\r\n        {\r\n            Task response = Task.Run(async () =&gt;\r\n            {\r\n                int count = 0;\r\n                while (++count &lt;= 10)\r\n                {\r\n                    await responseStream.WriteAsync(new MessageResponse { Message = $&quot;{count}. \u0130stek al\u0131nd\u0131 ve i\u015flendi...&quot; });\r\n                    await Task.Delay(1000);\r\n                }\r\n            });\r\n\r\n            Task request = Task.Run(async () =&gt;\r\n            {\r\n                while (await requestStream.MoveNext())\r\n                {\r\n                    Console.WriteLine($&quot;Mesaj al\u0131nm\u0131\u015ft\u0131r.&quot;);\r\n                    Console.WriteLine(&quot;Gelen mesaj : &quot;);\r\n                    Console.WriteLine(requestStream.Current.Message);\r\n                }\r\n            });\r\n\r\n            await response;\r\n            await request;\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki servise g\u00f6z atarsak e\u011fer <strong><em>5.<\/em><\/strong> sat\u0131rda istek neticesinde &#8216;MessageResponse&#8217; stream&#8217;i g\u00f6nderilmekte ve <strong><em>15.<\/em><\/strong> sat\u0131rda ise gelen stream data t\u00fcketilmektedir. Tabi burada asenkron bir s\u00fcre\u00e7 s\u00f6z konusu oldu\u011fu i\u00e7in ilgili i\u015flevlerin yer de\u011fi\u015ftirmesine gerek g\u00f6r\u00fclmemektedir. Ayr\u0131ca gRPC&#8217;de gelen request&#8217;e response d\u00f6nd\u00fcrebilmek i\u00e7in illaki ilgili request&#8217;in neticelenmesini beklemeye gerek olmayaca\u011f\u0131ndan dolay\u0131, request ile datalar gelirken bir yandan da response ile g\u00f6nderilebilmektedir.<\/p>\n<h4 style=\"color:purple;\">Client<\/h4>\n<p>\u0130stek g\u00f6nderecek client\u2019\u0131n a\u015fa\u011f\u0131daki gibi geli\u015ftirilmesi yeterli olacakt\u0131r;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static async Task Main(string&#x5B;] args)\r\n        {\r\n            var channel = GrpcChannel.ForAddress(&quot;https:\/\/localhost:5001&quot;);\r\n            var messageClient = new Message.MessageClient(channel);\r\n            Console.WriteLine(&quot;L\u00fctfen g\u00f6nderilecek mesaj\u0131 giriniz.&quot;);\r\n            var getMessage = messageClient.GetMessage();\r\n\r\n            Task request = Task.Run(async () =&gt;\r\n            {\r\n                int count = 0;\r\n                while (++count &lt;= 10)\r\n                {\r\n                    await getMessage.RequestStream.WriteAsync(new MessageRequest { Message = $&quot;G\u00f6nderilen mesaj {count}&quot; });\r\n                    await Task.Delay(1000);\r\n                }\r\n            });\r\n\r\n            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();\r\n            Task response = Task.Run(async () =&gt;\r\n            {\r\n                while (await getMessage.ResponseStream.MoveNext(cancellationTokenSource.Token))\r\n                    Console.WriteLine(getMessage.ResponseStream.Current.Message);\r\n            });\r\n            await request;\r\n            \/\/RequestStream ba\u015far\u0131yla sonland\u0131r\u0131l\u0131yor. \u00d6zellikle request'ten sonra olmas\u0131na \u00f6zen g\u00f6steriyoruz.\r\n            await getMessage.RequestStream.CompleteAsync();\r\n            await response;\r\n        }\r\n    }\r\n<\/pre>\n<p>Client uygulamas\u0131n\u0131n kodlar\u0131na g\u00f6z atarsan\u0131z e\u011fer, <strong><em>10.<\/em><\/strong> sat\u0131rda istek ile birlikte g\u00f6nderilecek stream data haz\u0131rlan\u0131rken, <strong><em>21.<\/em><\/strong> sat\u0131rda ise istek neticesinde e\u015fzamans\u0131z bir \u015fekilde gelen response stream data t\u00fcketilmektedir. Tabi burada <em>CancellationToken<\/em> kullan\u0131larak asenkron s\u00fcrecin rahatl\u0131kla y\u00f6netilebildi\u011fine dikkatinizi \u00e7ekerim.<\/p>\n<h4 style=\"color:purple;\">Test Edelim<\/h4>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/gRPC-Bi-directional-Streaming-Yontemiyle-Client-ve-Server-Iletisimi.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/gRPC-Bi-directional-Streaming-Yontemiyle-Client-ve-Server-Iletisimi.gif\" alt=\"gRPC - Bi-directional Streaming Y\u00f6ntemiyle Client ve Server \u0130leti\u015fimi\" width=\"800\" height=\"379\" class=\"aligncenter size-full wp-image-20581\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Bi-directional Streaming y\u00f6ntemiyle client ve server aras\u0131nda ba\u015far\u0131yla ileti\u015fim kurulabilmekte ve yap\u0131lan stream request\u2019e kar\u015f\u0131l\u0131k stream response elde edilebilmektedir.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle\u2026<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere\u2026<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar dilerim\u2026<\/p>\n<p>Not : \u00d6rnek projeleri indirebilmek i\u00e7in a\u015fa\u011f\u0131daki adreslere t\u0131klay\u0131n\u0131z.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/gRPCClientExample-4.zip\">gRPCClientExample<\/a><br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/gRPCServerExample-3.zip\">gRPCServerExample<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde, iki uygulama aras\u0131nda ileti\u015fimin gRPC \u00fczerinden Bi-directional y\u00f6ntemiyle nas\u0131l sa\u011fland\u0131\u011f\u0131n\u0131 pratikte inceliyor olaca\u011f\u0131z. \u0130lk olarak Bi-directional y\u00f6nteminin ne oldu\u011funu hat\u0131rlayarak ba\u015flayal\u0131m. Bi-directional Streaming, \u00f6nceden ele ald\u0131\u011f\u0131m\u0131z Client Streaming ile Server Streaming&#8216;in&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":20395,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4032],"tags":[4056,4065,4078,4079],"class_list":["post-20567","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-grpc","tag-bi-directional-streaming","tag-grpc","tag-grpc-bi-directional","tag-grpc-bi-directional-iletisim"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20567","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=20567"}],"version-history":[{"count":11,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20567\/revisions"}],"predecessor-version":[{"id":20584,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20567\/revisions\/20584"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/20395"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=20567"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=20567"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=20567"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}