{"id":376,"date":"2009-10-06T15:54:40","date_gmt":"2009-10-06T07:54:40","guid":{"rendered":"http:\/\/www.andreanolanusse.com\/pt\/?p=376"},"modified":"2013-05-04T23:48:25","modified_gmt":"2013-05-05T06:48:25","slug":"utilizando-callback-em-datasnap-2010","status":"publish","type":"post","link":"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/","title":{"rendered":"Utilizando callback em DataSnap 2010"},"content":{"rendered":"<p>Solicita\u00e7\u00e3o n\u00famero 1 dos usu\u00e1rios de DataSnap, suporte a callback, <a href=\"http:\/\/www.andreanolanusse.com\/pt\/tag\/datasnap\/\">DataSnap<\/a> 2010 permite a execu\u00e7\u00e3o de server methods utilizando callback, em outras palavras, \u00e9 esperar que o servidor envie retornos a aplica\u00e7\u00e3o cliente durante o processamento. Para exemplicar melhor, imagine os famosos fechamentos de final do m\u00eas, estes s\u00e3o disparados a partir de uma aplica\u00e7\u00e3o cliente que somente recebe um retorno ao finalizar o processo do lado servidor, com callback podemos notificar a aplica\u00e7\u00e3o cliente como est\u00e1 o processamento do lado servidor.<br \/>\nA classe TDBXCallback \u00e9 respons\u00e1vel pelo callback, assim voc\u00ea dever\u00e1 criar uma classe descendente, implementar o m\u00e9todo execute e passar como par\u00e2metro no seu server method. O servidor ir\u00e1 executar o m\u00e9todo Execute do par\u00e2metro de callback enviado ao servidor, na verdade o servidor est\u00e1 notificando o cliente para executar algum c\u00f3digo.<\/p>\n<p>Para melhor exemplificar, vamos imaginar que voc\u00ea precisa fazer o backup da sua base de dados a partir de uma instru\u00e7\u00e3o enviada pela aplica\u00e7\u00e3o cliente para o servidor, durante o processo de backup voc\u00ea deseja saber como est\u00e1 o andamento do backup, esta \u00e9 uma tarefa para o callback, o c\u00f3digo faz exatamento isso, backup de uma base de dados <strong><a href=\"http:\/\/www.embarcadero.com\/products\/interbase\">InterBase<\/a><\/strong> e retorna o log para a aplica\u00e7\u00e3o cliente.<\/p>\n<p>Para come\u00e7ar temos que implementar o server method que ser\u00e1 respons\u00e1vel por executar o backup, este obrigatoriamente necessita um par\u00e2metro do tipo TDBXCallback o qual ser\u00e1 respons\u00e1vel por enviar a notifica\u00e7\u00e3o a aplica\u00e7\u00e3o cliente atrav\u00e9s do m\u00e9todo Execute.<\/p>\n<p>O m\u00e9todo Execute por sua vez recebe envia um TJSONObject o qual cont\u00e9m um TJSONPair com as mensagens do log de backup da base de dados, lembre-se que eu optei por enviar apenas um valor dentro do objeto e a cada linha de log recebida o cliente ser\u00e1 notificado que h\u00e1 uma mensagem nova.<\/p>\n<pre class=\"brush: delphi\">procedure TDSServerBatch.StartBackup(sMessage: TDBXCallback;\r\n  sBackupFileName: String);\r\nvar\r\n  LCallbackValue: TJSONObject;\r\n  db: String;\r\n\r\nbegin\r\n\r\n  db := DMServerContainer.GetEmployeeDBName;\r\n\r\n  srvBackup.DatabaseName := Copy(db, Pos(':', db) + 1, Length(db));\r\n\r\n  srvBackup.Attach;\r\n  srvBackup.BackupFile.Add(sBackupFileName);\r\n\r\n  srvBackup.ServiceStart;\r\n  if srvBackup.Verbose then\r\n    while not srvBackup.Eof do\r\n    begin\r\n\r\n      \/\/ if srvBackup.IsServiceRunning then\r\n      begin\r\n        LCallbackValue := TJSONObject.Create;\r\n        LCallbackValue.AddPair(TJSONPair.Create('Server return',\r\n            srvBackup.GetNextLine));\r\n\r\n        sMessage.Execute(LCallbackValue);\r\n\r\n      end;\r\n\r\n    end;\r\n\r\n  if srvBackup.Active then\r\n    srvBackup.Detach();\r\n\r\nend;<\/pre>\n<p>Vamos agora ao lado cliente, como temos que passar um par\u00e2metro do tipo TDBXCallback ent\u00e3o teremos que criar e implementar a tal classe. Vem a pergunta, para cada server method que necessita efetuar callback terei que criar uma classe de callback? A resposta \u00e9 n\u00e3o, neste exemplo utilizaremos anonymous method para evitar isso.<\/p>\n<p>Abaixo a classe de callback que estarei utilizando, veja que o m\u00e9todo execute recebe um par\u00e2metro do tipo TDSCallbackMethod o qual \u00e9 um anonymous method, desta forma na cria\u00e7\u00e3o da inst\u00e2ncia desta classe ser\u00e1 passado o c\u00f3digo a ser executando quando o servidor executar o m\u00e9todo Execute.<\/p>\n<pre class=\"brush: delphi\">type\r\n  TDSCallbackMethod = reference to function(const Args: TJSONValue): TJSONValue;\r\n\r\n  TMessageCallback = class(TDBXCallback)\r\n  private\r\n    FCallBackMethod: TDSCallbackMethod;\r\n\r\n  public\r\n    constructor Create(CallBackMethod: TDSCallbackMethod);\r\n    function Execute(const Arg: TJSONValue): TJSONValue; override;\r\n  end;\r\n\r\nimplementation\r\n\r\nconstructor TMessageCallback.Create(CallBackMethod: TDSCallbackMethod);\r\nbegin\r\n  FCallBackMethod := CallBackMethod;\r\nend;\r\n\r\nfunction TMessageCallback.Execute(const Arg: TJSONValue): TJSONValue;\r\nbegin\r\n  Result := FCallbackMethod(Arg);\r\nend;<\/pre>\n<p>Com a classe de callback definida, temos agora que implementar o anonymous method e executar o server method conforme o exemplo a seguir.<\/p>\n<p>Veja que o par\u00e2metro Args do anonymous method \u00e9 do tipo TJSONValue, extraimos os valores TJSONPair onde se encontra o log do backup.<\/p>\n<pre class=\"brush: delphi\">var\r\n  s : TDSServerBatchClient;\r\nbegin\r\n\r\n  callback := TMessageCallback.Create( function(const Args: TJSONValue) : TJSONValue\r\n\r\n    var\r\n     LJSONObject: TJSONObject; I: Integer;\r\n     LMessage: string;\r\n    begin\r\n      \/\/ Extract information about the transformation from Json\r\n      LJSONObject := TJSONObject(Args);\r\n      Result := nil;\r\n\r\n      for I := 0 to LJSONObject.Size - 1 do begin\r\n         with LJSONObject.Get(I) do\r\n           LMessage := LMessage + Format('%s ==&gt;&gt; \"%s\"', [JSonString.Value, JsonValue.Value]);\r\n\r\n      \/\/ Display information in a listbox\r\n        MMBackupLog.Lines.Add(LMessage);\r\n        MMBackupLog.Update;\r\n        Result := TJSONTrue.Create;\r\n\r\n      end;\r\n    end);<\/pre>\n<p>Na sequ\u00eancia apenas executamos o m\u00e9todo, passando a classe callback com par\u00e2metro e o anonymous method ser\u00e1 respons\u00e1vel por adicionar a mensagem de retorno no campo memo que est\u00e1 na tela, utilizado neste exemplo.<\/p>\n<pre class=\"brush: delphi\">  s := TDSServerBatchClient.Create(DMClientContainer.MyDSServer.DBXConnection);\r\n  s.StartBackup(callback, 'mybackup.ibk');<\/pre>\n<p>Espero que este post tenha esclarecido as d\u00favidas relacionadas a callback.<\/p>\n<p>Download do <a href=\"http:\/\/cc.embarcadero.com\/item\/27391\">c\u00f3digo fonte<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Solicita\u00e7\u00e3o n\u00famero 1 dos usu\u00e1rios de DataSnap, suporte a callback, DataSnap 2010 permite a execu\u00e7\u00e3o de server methods utilizando callback, em outras palavras, \u00e9 esperar que o servidor envie retornos a aplica\u00e7\u00e3o cliente durante o processamento. Para exemplicar melhor, imagine os famosos fechamentos de final do m\u00eas, estes s\u00e3o disparados a partir de uma aplica\u00e7\u00e3o [&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":"yes","footnotes":""},"categories":[102],"tags":[23,181,29],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Como utilizar callback em DataSnap 2010 | Delphi 2010<\/title>\n<meta name=\"description\" content=\"Solicita\u00e7\u00e3o n\u00famero 1 dos usu\u00e1rios de DataSnap, suporte a callback, DataSnap 2010 permite a execu\u00e7\u00e3o de server methods utilizando callback, em outras\" \/>\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\/utilizando-callback-em-datasnap-2010\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Como utilizar callback em DataSnap 2010 | Delphi 2010\" \/>\n<meta property=\"og:description\" content=\"Solicita\u00e7\u00e3o n\u00famero 1 dos usu\u00e1rios de DataSnap, suporte a callback, DataSnap 2010 permite a execu\u00e7\u00e3o de server methods utilizando callback, em outras\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/\" \/>\n<meta property=\"og:site_name\" content=\"Andreano Lanusse | Tecnologia e Desenvolvimento de Software\" \/>\n<meta property=\"article:published_time\" content=\"2009-10-06T07:54:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-05-05T06:48:25+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\/utilizando-callback-em-datasnap-2010\/#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\/utilizando-callback-em-datasnap-2010\/#webpage\",\"url\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/\",\"name\":\"Como utilizar callback em DataSnap 2010 | Delphi 2010\",\"isPartOf\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#primaryimage\"},\"datePublished\":\"2009-10-06T07:54:40+00:00\",\"dateModified\":\"2013-05-05T06:48:25+00:00\",\"description\":\"Solicita\\u00e7\\u00e3o n\\u00famero 1 dos usu\\u00e1rios de DataSnap, suporte a callback, DataSnap 2010 permite a execu\\u00e7\\u00e3o de server methods utilizando callback, em outras\",\"breadcrumb\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#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\/utilizando-callback-em-datasnap-2010\/#webpage\"}}]},{\"@type\":\"Article\",\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#article\",\"isPartOf\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#webpage\"},\"author\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"headline\":\"Utilizando callback em DataSnap 2010\",\"datePublished\":\"2009-10-06T07:54:40+00:00\",\"dateModified\":\"2013-05-05T06:48:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#webpage\"},\"commentCount\":4,\"publisher\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/#\/schema\/person\/620bd05e81598c3aba4781796cbe8903\"},\"image\":{\"@id\":\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#primaryimage\"},\"keywords\":[\"DataSnap\",\"Delphi\",\"JSON\"],\"articleSection\":[\"Delphi\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"http:\/\/www.andreanolanusse.com\/pt\/utilizando-callback-em-datasnap-2010\/#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\/376"}],"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=376"}],"version-history":[{"count":0,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/posts\/376\/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=376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/categories?post=376"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.andreanolanusse.com\/pt\/wp-json\/wp\/v2\/tags?post=376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}