{"id":4211,"date":"2012-08-01T09:15:47","date_gmt":"2012-08-01T16:15:47","guid":{"rendered":"http:\/\/www.andreanolanusse.com\/pt\/?p=4211"},"modified":"2014-03-03T21:02:28","modified_gmt":"2014-03-04T05:02:28","slug":"monitoramento-e-controle-de-conexoes-em-servidores-datasnap","status":"publish","type":"post","link":"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/","title":{"rendered":"Monitoramento e controle de conex\u00f5es em servidores DataSnap"},"content":{"rendered":"<p>A vers\u00e3o do DataSnap que acompanha o Delphi XE2 finalmente trouxe o t\u00e3o esperado e solicitado recurso para controlar e monitorar conex\u00f5es efetuadas atrav\u00e9s de TCP\/IP em um servidor DataSnap, at\u00e9 a vers\u00e3o XE o monitoramento e controle era poss\u00edvel, entretanto requeria muito c\u00f3digo por parte do desenvolvedor. No Delphi XE2 o framework do DataSnap traz classes e m\u00e9todos que facilitam e muito isso e neste artigo vou explicar como funciona.<\/p>\n<p>Pra come\u00e7ar, toda a implementa\u00e7\u00e3o do monitoramento e controle est\u00e1 implementada para protocolo TCP\/IP o que permite monitorar e derrubar qualquer conex\u00e3o, assim sendo o componente TDSTCPServerTransporter recebeu dois novos eventos OnConnect e OnDisconnect, estes eventos s\u00e3o muito importantes, pois atrav\u00e9s deles gerenciamos a lista de conex\u00f5es no servidor podendo fazer o que quiser com as mesmas. Al\u00e9m disso toda conex\u00e3o est\u00e1 associado a um Session ID que \u00e9 \u00fanico, o Session ID j\u00e1 est\u00e1 dispon\u00edvel desde as vers\u00f5es anteriores do DataSnap.<\/p>\n<p>Para exemplificar o funcionamento e implementa\u00e7\u00e3o do monitoramento definimos uma lista (collection) conforme abaixo para armazenar as inst\u00e2ncias de cada conex\u00e3o (TIdTCPConnection) e protocolo (TDSTCPChannel)<\/p>\n<pre class=\"brush: delphi\">FConnections: TObjectDictionary&lt;TIdTCPConnection,TDSTCPChannel&gt;;<\/pre>\n<p>&nbsp;<\/p>\n<p>A partir dai implementamos os eventos OnConnect e OnDisconnect no TDSTCPServerTransporter. Implementar o evento OnConnect \u00e9 bem simples, voc\u00ea tem apenas que armazenar as informa\u00e7\u00f5es referente a conex\u00e3o na sua lista e caso tenha alguma interface para atualizar com as informa\u00e7\u00f5es referentes a esta conex\u00e3o, assim faze-lo.<\/p>\n<p>O c\u00f3digo abaixo adiciona a nova conex\u00e3o utilizando os m\u00e9todos TMonitor.Enter e TMonitor.Exit para assegurar que nenhuma outra thread ir\u00e1 tentar atualizar esta lista.<\/p>\n<p>Ap\u00f3s adicionar a lista utilizamos o m\u00e9todo EnableKeepAlive que irei explicar em seguida.<\/p>\n<pre class=\"brush: delphi\">procedure TCMServerForm.CMServerTransportConnectEvent(Event: TDSTCPConnectEventObject);\r\nbegin\r\n  System.TMonitor.Enter(FConnections);\r\n  try\r\n    FConnections.Add(TIdTCPConnection(Event.Connection), Event.Channel);\r\n  finally\r\n    System.TMonitor.Exit(FConnections);\r\n  end;\r\n\r\n  \/\/Enable Keep-alive for this new connection.\r\n    Event.Channel.EnableKeepAlive(10000);\r\nend;<\/pre>\n<p>A implementa\u00e7\u00e3o do m\u00e9todo OnDisconnect ter\u00e1 que localizar a inst\u00e2ncia da conex\u00e3o e remove-la da lista, OnDisconnect ser\u00e1 executado quando a aplica\u00e7\u00e3o cliente desconectar do servidor, seja de forma natural, queda de rede, etc.<\/p>\n<p>Por padr\u00e3o, o evento\u00a0OnDisconnect\u00a0n\u00e3o ser\u00e1 notificado\u00a0se o cliente\u00a0de forma abrupta\u00a0perde sua conex\u00e3o\u00a0internet.\u00a0Isso acontece porque a conex\u00e3o Socket permanece aberta at\u00e9 que ocorra alguma chamada e esta falhe.\u00a0Se o sistema operacional est\u00e1 configurado para usar\u00a0pacotes keep-alive\u00a0para todas as conex\u00f5es\u00a0TCP\/IP e com base na sua\u00a0configura\u00e7\u00e3o, voc\u00ea\u00a0ver\u00e1 o\u00a0evento OnDisconnect ser notificado.\u00a0Se voc\u00ea\u00a0desejar controlar este comportamento\u00a0para cada conex\u00e3o, ent\u00e3o use os m\u00e9todos EnableKeepAlive e DisableKeepAlive para cada inst\u00e2ncia do TDSTCPChannel.<\/p>\n<p>No c\u00f3digo acima foi definido para cada conex\u00e3o o KeepAlive em 10 segundos, isso quer dizer que o server ir\u00e1 enviar um pacote (fazer um ping) no cliente quando o mesmo estiver inativo por mais de 10 segundos, se o cliente n\u00e3o responder o server ir\u00e1 tentar novamente, a quantidade de tentativas \u00e9 baseada no sistema operacional, por exemplo Windows 7 tenta 10 vezes. Voc\u00ea ainda pode definir o intervalo entre os pings, basta configurar o KeepAliveInterval.<\/p>\n<p>O c\u00f3digo abaixo demonstra como remover a inst\u00e2ncia da conex\u00e3o da lista e como atualizar a interface do usu\u00e1rio utilizando TThread.Synchronize.<\/p>\n<pre class=\"brush: delphi\">procedure TCMServerForm.CMServerTransportDisconnectEvent(Event: TDSTCPDisconnectEventObject);\r\nvar\r\n  Index: Integer;\r\nbegin\r\n  if (FConnections = nil) or (Event.Connection = nil) then\r\n    Exit;\r\n\r\n  \/\/This is called when a TCP connection is closed, for whatever reason.\r\n  System.TMonitor.Enter(FConnections);\r\n  try\r\n    FConnections.Remove(TIdTCPConnection(Event.Connection));\r\n\r\n    TThread.Synchronize(nil, procedure\r\n      begin\r\n        \/\/update the connection list box, removing the connection that was just closed\r\n        Index := ConnectionsList.Items.IndexOfObject(Event.Connection);\r\n        if Index &gt; -1 then\r\n        begin\r\n          ConnectionsList.Items.Delete(Index);\r\n\r\n          if ConnectionsList.SelCount = 0 then\r\n            SessionIdList.ClearSelection;\r\n        end;\r\n      end);\r\n  finally\r\n    System.TMonitor.Exit(FConnections);\r\n  end;<\/pre>\n<p>At\u00e9 aqui sabemos quem est\u00e1 conectado ao servidor, a partir dai podemos derrubar qualquer conex\u00e3o, visto que temos a inst\u00e2ncia de cada TDSTCPChannel e este cont\u00e9m o m\u00e9todo close que encerra a conex\u00e3o cliente, ao ser desconectado o lado cliente recebe uma exception quando tentar executar qualquer opera\u00e7\u00e3o no servidor.<br \/>\nNo exemplo abaixo encerramos a conex\u00e3o selecionada em um ListBox, o m\u00e9todo GetSelectedChannel busca a inst\u00e2ncia do Channel baseado na conex\u00e3o selecionada no ListBox.<\/p>\n<p>Quando executamos o m\u00e9todo Channel.Close o evento OnDisconnect ser\u00e1 notificado.<\/p>\n<pre class=\"brush: delphi\">procedure TCMServerForm.ButtCloseSelectedClick(Sender: TObject);\r\nvar\r\n  Channel: TDSTCPChannel;\r\nbegin\r\n  \/\/Find the selected connection's channel, and then close it.\r\n  Channel := GetSelectedChannel;\r\n\r\n  \/\/after calling close, the CMServerTransportDisconnectEvent event will be notified.\r\n  if Channel &lt;&gt; nil then\r\n  begin\r\n    Channel.Close;\r\n  end;\r\nend;\r\nfunction TCMServerForm.GetSelectedChannel(Conn: TIdTCPConnection): TDSTCPChannel;\r\nbegin\r\n  Result := nil;\r\n\r\n  \/\/Finds the selected connection\r\n  if Conn = nil then\r\n    Conn := GetSelectedConnection;\r\n\r\n  \/\/uses the selected connection to look up the associated channel.\r\n  if Conn &lt;&gt; nil then\r\n    FConnections.TryGetValue(Conn, Result)\r\nend;<\/pre>\n<p>O Delphi XE2 traz um exemplo completo sobre o assunto e se voc\u00ea j\u00e1 usa a vers\u00e3o XE2 pode encontr\u00e1-lo em C:\\Users\\Public\\Documents\\RAD Studio\\9.0\\Samples\\Delphi\\DataSnap\\DataSnapMonitor ou fazer o download direto do reposit\u00f3rio de demos do RAD Studio XE2 <a href=\"http:\/\/radstudiodemos.svn.sourceforge.net\/viewvc\/radstudiodemos\/branches\/RadStudio_XE2\/Delphi\/DataSnap\/DataSnapMonitor\/\" target=\"_blank\">aqui<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A vers\u00e3o do DataSnap que acompanha o Delphi XE2 finalmente trouxe o t\u00e3o esperado e solicitado recurso para controlar e monitorar conex\u00f5es efetuadas atrav\u00e9s de TCP\/IP em um servidor DataSnap, at\u00e9 a vers\u00e3o XE o monitoramento e controle era poss\u00edvel, entretanto requeria muito c\u00f3digo por parte do desenvolvedor. No Delphi XE2 o framework do DataSnap [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4202,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_s2mail":"no","footnotes":""},"categories":[102],"tags":[23,181],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Monitoramento e controle de conex\u00f5es em servidores DataSnap | Andreano Lanusse | Tecnologia e Desenvolvimento de Software<\/title>\n<meta name=\"description\" content=\"Aprenda como monitorar e ter total controle das conex\u00f5es que chegam ao seu servidor DataSnap, a partir do Delphi XE2 isso \u00e9 poss\u00edvel, este artigo explica como.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Monitoramento e controle de conex\u00f5es em servidores DataSnap | Andreano Lanusse | Tecnologia e Desenvolvimento de Software\" \/>\n<meta property=\"og:description\" content=\"Aprenda como monitorar e ter total controle das conex\u00f5es que chegam ao seu servidor DataSnap, a partir do Delphi XE2 isso \u00e9 poss\u00edvel, este artigo explica como.\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/\" \/>\n<meta property=\"og:site_name\" content=\"Andreano Lanusse | Tecnologia e Desenvolvimento de Software\" \/>\n<meta property=\"article:published_time\" content=\"2012-08-01T16:15:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-03-04T05:02:28+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.andreanolanusse.com\/pt\/wp-content\/uploads\/2011\/09\/Icon_Delphi.png\" \/>\n\t<meta property=\"og:image:width\" content=\"170\" \/>\n\t<meta property=\"og:image:height\" content=\"170\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@andreanolanusse\" \/>\n<meta name=\"twitter:site\" content=\"@andreanolanusse\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\">\n\t<meta name=\"twitter:data1\" content=\"4 minutos\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#website\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/\",\"name\":\"Andreano Lanusse | Tecnologia e Desenvolvimento de Software\",\"description\":\"Andreano Lanusse blog - artigos, tutoriais e v&iacute;deos sobre tecnologia, desenvolvimento de software (Delphi XE4, C#, PHP, .NET) e t&eacute;cnicas de programa&ccedil;&atilde;o\",\"publisher\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"http:\/\/www.andreanolanusse.com\/pt\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#primaryimage\",\"inLanguage\":\"pt-BR\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/wp-content\/uploads\/2011\/09\/Icon_Delphi.png\",\"contentUrl\":\"http:\/\/www.andreanolanusse.com\/pt\/wp-content\/uploads\/2011\/09\/Icon_Delphi.png\",\"width\":170,\"height\":170},{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#webpage\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/\",\"name\":\"Monitoramento e controle de conex\\u00f5es em servidores DataSnap | Andreano Lanusse | Tecnologia e Desenvolvimento de Software\",\"isPartOf\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#primaryimage\"},\"datePublished\":\"2012-08-01T16:15:47+00:00\",\"dateModified\":\"2014-03-04T05:02:28+00:00\",\"description\":\"Aprenda como monitorar e ter total controle das conex\\u00f5es que chegam ao seu servidor DataSnap, a partir do Delphi XE2 isso \\u00e9 poss\\u00edvel, este artigo explica como.\",\"breadcrumb\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/\",\"name\":\"In\\u00edcio\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#webpage\"}}]},{\"@type\":\"Article\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#article\",\"isPartOf\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#webpage\"},\"author\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"headline\":\"Monitoramento e controle de conex\\u00f5es em servidores DataSnap\",\"datePublished\":\"2012-08-01T16:15:47+00:00\",\"dateModified\":\"2014-03-04T05:02:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#webpage\"},\"commentCount\":7,\"publisher\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"image\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#primaryimage\"},\"keywords\":[\"DataSnap\",\"Delphi\"],\"articleSection\":[\"Delphi\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"http:\/\/www.andreanolanusse.com\/pt\/monitoramento-e-controle-de-conexoes-em-servidores-datasnap\/#respond\"]}]},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\",\"name\":\"Andreano Lanusse\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#personlogo\",\"inLanguage\":\"pt-BR\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/6a9c6f73c7c480fb826c7303288abfd3?s=96&d=mm&r=g\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/6a9c6f73c7c480fb826c7303288abfd3?s=96&d=mm&r=g\",\"caption\":\"Andreano Lanusse\"},\"logo\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#personlogo\"},\"sameAs\":[\"https:\/\/twitter.com\/andreanolanusse\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts\/4211"}],"collection":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/comments?post=4211"}],"version-history":[{"count":0,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts\/4211\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/media\/4202"}],"wp:attachment":[{"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/media?parent=4211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/categories?post=4211"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/tags?post=4211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}