{"id":2704,"date":"2017-02-23T00:41:05","date_gmt":"2017-02-23T04:41:05","guid":{"rendered":"http:\/\/linguagemprisma.br4.biz\/blog\/?p=2704"},"modified":"2017-02-23T10:08:55","modified_gmt":"2017-02-23T14:08:55","slug":"criando-um-aplicativo-cliente-servidor-em-prisma","status":"publish","type":"post","link":"https:\/\/linguagemprisma.br4.biz\/blog\/modo_texto\/criando-um-aplicativo-cliente-servidor-em-prisma\/","title":{"rendered":"Criando um aplicativo cliente \/ servidor em Prisma"},"content":{"rendered":"<p>Vamos criar um mini messenger, na verdade o esqueleto de um s\u00f3 para ter como base para criar outros.<\/p>\n<p>Antes baixe a vers\u00e3o mais atual Prisma, 1.0.99 ou superior.<\/p>\n<p>(Testado em Ubuntu 12.04, Mint17, Mint18 e Windows7,10)<\/p>\n<h1>1- Servidor<\/h1>\n<p>Primeiramente, vamos criar o servidor, programa que vai receber as mensagens do cliente. Salve como servidor.prisma, e copie o c\u00f3digo abaixo:<\/p>\n<pre class=\"lang:prisma decode:true\">inclua'igrede';\r\ninclua 'igbr';\r\n\r\nbloco_tam = 1024;\/\/tamanho do bloco; 1024 caracteres\r\n\r\n\/\/funcao principal\r\nfuncao principal()\r\n    local servidor = igrede.servidor();\r\n    ret, erro_msg = igrede.escute_porta(servidor, 2345);\r\n    se ret == falso entao\r\n         imprima(erro_msg);\r\n         sis.saia(1);\r\n    fim\r\n    \r\n    ig.conecte_funcao(servidor,ig.recebido, call_servidor,nulo);\r\n    \r\n    igrede.servidor_inicie(servidor);\r\n    imprima'Servidor ativo, esperando conexao com cliente';\r\n    ig.fimprograma();\r\n    igrede.servidor_pare(servidor);\r\n    retorne 0;\r\nfim \/\/fim principal\r\n\r\n\r\nfuncao ao_ler(mensagem,dado)\r\n   imprima(\"Cliente: \" .. mensagem);\r\nfim\r\n\r\nfuncao call_servidor( servidor,conexao, Gobjeto, dado)\r\n   imprima(\"Conexao recebida de cliente\\n\");\r\n   igrede.leia_assinc( conexao, bloco_tam, ao_ler,dado);\/\/executa leitura assincrona, com 1024 bytes de tamanho.\r\nfim\r\n\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Vamos aos detalhes:<\/p>\n<pre class=\"lang:prisma decode:true\">inclua'igrede';\r\ninclua 'igbr';<\/pre>\n<p>No trecho acima inclu\u00edmos as bibliotecas necess\u00e1rias, veja que igbr \u00e9 necess\u00e1ria mesmo que n\u00e3o usemos interface gr\u00e1fica.<\/p>\n<p>As duas bibliotecas acima trabalham juntas.<\/p>\n<hr \/>\n<pre class=\"lang:prisma decode:true\">bloco_tam = 1024;\/\/tamanho do bloco; 1024 caracteres<\/pre>\n<p>Na linha acima definimos qual ser\u00e1 o tamanho m\u00e1ximo de cada dado enviado ao servidor. 1024 bytes \u00e9 o limite, correspondente a 1Kb aproximadamente.<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\">funcao principal()<\/pre>\n<p>Aqui iniciamos a fun\u00e7\u00e3o principal(), o mesmo que main() do C.<\/p>\n<hr \/>\n<pre class=\"lang:prisma decode:true\"> local servidor = igrede.servidor();<\/pre>\n<p>A fun\u00e7\u00e3o acima cria um ponteiro servidor e salva em uma vari\u00e1vel.<\/p>\n<pre class=\"lang:prisma decode:true\">ret, erro_msg = igrede.escute_porta(servidor, 2345);<\/pre>\n<p>Aqui fazemos o servidor escutar na porta 2345;<\/p>\n<p><strong>Par\u00e2metros:<\/strong><\/p>\n<p>1- servidor criado com a fun\u00e7\u00e3o igrede.servidor();<\/p>\n<p>2 &#8211; N\u00famero da porta, tome cuidado para que a porta n\u00e3o seja a mesma que outro programa use, ex.: servidor usa porta 80, Mysql usa 3306 etc.<\/p>\n<p><strong>Retornos:<\/strong><\/p>\n<p>1 &#8211; ret: \u00e9 um boleando falso para erro.<\/p>\n<p>2 &#8211; erro_msg: mensagem de erro em string.<\/p>\n<p>(Talvez eu modifique estes retornos, n\u00e3o faz sentido dois)<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\">se ret == falso entao\r\n         imprima(erro_msg);\r\n         sis.saia(1);\r\n    fim<\/pre>\n<p>Acima \u00e9 feito o tratamento de erro. Se ret for igual a falso ent\u00e3o a mensagem de erro \u00e9 impressa e o programa \u00e9 fechado.<\/p>\n<pre class=\"lang:prisma decode:true\"> ig.conecte_funcao(servidor,ig.recebido, call_servidor,nulo);<\/pre>\n<p>Conectamos uma fun\u00e7\u00e3o callback (call_servidor) ao evento recebido do servidor. Ou seja, cada vez que o servidor receber algo do cliente esta fun\u00e7\u00e3o ser\u00e1 executada. O \u00faltimo par\u00e2metro (dado extra) \u00e9 nulo pois n\u00e3o vamos us\u00e1-lo.<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\">igrede.servidor_inicie(servidor);<\/pre>\n<p>No trecho acima, iniciamos o servidor, passamos a vari\u00e1vel do servidor com par\u00e2metro para fun\u00e7\u00e3o igrede.servidor_inicie();<\/p>\n<p>Ap\u00f3s isso, imprimimos a frase de espera:<\/p>\n<pre class=\"lang:prisma decode:true\">imprima'Servidor ativo, esperando conexao com cliente';<\/pre>\n<hr \/>\n<pre class=\"lang:prisma decode:true\"> ig.fimprograma();<\/pre>\n<p>A fun\u00e7\u00e3o acima inicia o la\u00e7o de eventos do igbr. Ao chegar aqui o programa entra em modo repeti\u00e7\u00e3o esperando eventos como clique do mouse, tecla pressionada etc. O que estiver ap\u00f3s esse comando s\u00f3 ser\u00e1 executado quando o la\u00e7o for interrompido.<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\"> igrede.servidor_pare(servidor);\r\n retorne 0;\r\nfim \/\/fim principal<\/pre>\n<p>Este \u00faltimo comando, como pode-se perceber pelo nome, finaliza o servidor.<\/p>\n<p>Enfim, \u00e9 retornado 0 e fechamos a fun\u00e7\u00e3o principal com seu respectivo fim.<\/p>\n<p>Vamos para as fun\u00e7\u00f5es callbacks:<\/p>\n<pre class=\"lang:prisma decode:true\">funcao ao_ler(mensagem,dado)\r\n   imprima(\"Cliente: \" .. mensagem);\r\nfim<\/pre>\n<p>Esta fun\u00e7\u00e3o est\u00e1 conectada \u00e0 leitura do servidor. Ao ser executada automaticamente pela fun\u00e7\u00e3o leia_assinc() ela recebe a mensagem recebida e o dado extra.<\/p>\n<pre class=\"lang:prisma decode:true\">funcao call_servidor( servidor, conexao, Gobjeto, dado)\r\n<\/pre>\n<p>Esta fun\u00e7\u00e3o acima foi conectada ao evento recebido do servidor, logo ela ser\u00e1 executada sempre que o servidor receber uma mensagem do cliente. Seus par\u00e2metros s\u00e3o passados automaticamente a cada execu\u00e7\u00e3o da fun\u00e7\u00e3o pelo evento &#8216;recebido&#8217;.<\/p>\n<p><strong>Par\u00e2metros da callback:<\/strong> Servidor ativo, a conex\u00e3o, o objeto, e o dado extra que no caso \u00e9 nulo, pois foi definido assim na fun\u00e7\u00e3o conecte_funcao();<\/p>\n<pre class=\"lang:prisma decode:true\">imprima(\"Conexao recebida de cliente\\n\");\r\n   igrede.leia_assinc( conexao, bloco_tam, ao_ler,dado);\/\/executa leitura assincrona, com 1024 bytes de tamanho.\r\nfim<\/pre>\n<p><strong>Corpo da fun\u00e7\u00e3o callback.<\/strong><\/p>\n<p>imprimimos a mensagem de conex\u00e3o recebida.<\/p>\n<p>usamos a fun\u00e7\u00e3o igrede.leia_assinc() para ler a mensagem.<\/p>\n<p><strong>Par\u00e2metros:<\/strong><\/p>\n<p>1 &#8211; conexao: ponteiro da conexao recebida, \u00e9 o segundo par\u00e2metro da callback.<\/p>\n<p>2 &#8211; tamanho em bytes m\u00e1ximo para ler a mensagem.<\/p>\n<p>3 &#8211; fun\u00e7\u00e3o extra para receber a mensagem.<\/p>\n<p>Enfim, a fun\u00e7\u00e3o callback \u00e9 fechada com &#8216;fim&#8217;;<\/p>\n<p>Aqui finalizamos a primeira parte, e a mais complicada, agora vamos ao programa cliente.prisma:<\/p>\n<h1>2 &#8211; Cliente<\/h1>\n<p>&nbsp;<\/p>\n<p>Salve como cliente.prisma e copie o c\u00f3digo abaixo:<\/p>\n<pre class=\"lang:prisma decode:true\">socket = inclua'igrede'\r\n\r\ncliente = socket.cliente();\/\/cria um novo cliente socket\r\n\r\nrepita \/\/fazemos um laco repita para digitar as mensagens.\r\n imprima'Digite algo: [s = sair]'\r\n s = leia(); \r\n se s == 's' entao sis.saia(0); fim\r\n \/\/conectando-se ao servidor 'localhost' na porta 2345\r\n conexao , erro_msg = socket.cliente_conecte_com_servidor (cliente , \"192.168.1.12\", \/\/ip do servidor\r\n                                                2345 \/\/porta de conexao\r\n                                           );\r\n\r\nse conexao == nulo entao\r\n   imprima( erro_msg,'\\nConexao rejeitada, servidor desligado?' );\r\n   \/\/sis.saia(4);\r\nsenao\r\n   imprima(\"Enviado com sucesso para o servidor\");\r\n   erro_msg = socket.escreva( conexao , s  );\r\n   se erro_msg entao imprima(erro_msg) fim;\r\nfim\r\nate s == 's';\r\n\/\/fim\r\nsis.saia(0);\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Detalhes:<\/p>\n<pre class=\"lang:prisma decode:true\">socket = inclua'igrede'<\/pre>\n<p>Incluindo a biblioteca igrede. Aqui n\u00e3o precisamos da igbr.<\/p>\n<pre class=\"lang:prisma decode:true\">cliente = socket.cliente();\/\/cria um novo cliente socket\r\n<\/pre>\n<p>Criando um socket cliente e retornando na vari\u00e1vel cliente.<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\">repita \/\/fazemos um laco repita para digitar as mensagens.\r\n imprima'Digite algo: [s = sair]'<\/pre>\n<p>Vamos usar o comando repita como la\u00e7o de repeti\u00e7\u00e3o, poderia ser o enquanto se quisesse.<\/p>\n<p>Imprimimos a frase do cabe\u00e7alho do messenger.<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\"> s = leia();<\/pre>\n<p>Essa fun\u00e7\u00e3o aguarda o usu\u00e1rio digitar algo e pressionar ENTER, no nosso caso a frase para enviar ao servidor ou S para sair:<\/p>\n<pre class=\"lang:prisma decode:true\">se s == 's' entao sis.saia(0); fim<\/pre>\n<p>se o usu\u00e1rio digitar S o programa \u00e9 fechado.<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true \"> conexao , erro_msg = socket.cliente_conecte_com_servidor (cliente , \"192.168.1.12\", \/\/ip do servidor\r\n                                                2345 \/\/porta de conexao\r\n                                           );<\/pre>\n<p>A fun\u00e7\u00e3o que conecta ao servidor.<\/p>\n<p><strong>Par\u00e2metros:<\/strong><\/p>\n<p>1 &#8211; cliente: vari\u00e1vel ponteiro do cliente criado com a fun\u00e7\u00e3o socket.cliente();<\/p>\n<p>2 &#8211; Ip do servidor. Substitua por um ip v\u00e1lido em sua rede. Ou se estiver executando servidor e cliente no mesmo pc use &#8216;localhost&#8217;.<\/p>\n<p>3 &#8211; Porta do servidor. Use a mesma definida no servidor.prisma<\/p>\n<p><strong>Retornos:<\/strong><\/p>\n<p>1 &#8211; conexao: vari\u00e1vel ponteiro da conex\u00e3o com o servidor ou nulo caso a conex\u00e3o falhe.<\/p>\n<p>2 &#8211; erro_msg: string descrevendo mensagem de erro se houver.<\/p>\n<hr \/>\n<pre class=\"lang:prisma decode:true\">se conexao == nulo entao\r\n   imprima( erro_msg,'\\nConexao rejeitada, servidor desligado?' );\r\n   \/\/sis.saia(4);\r\n<\/pre>\n<p>Acima fazemos o tratamento de erro. Se conexao for nulo imprimimos o erro no terminal e poder\u00edamos sair do programa se quiser (des)comente a fun\u00e7\u00e3o sis.saia(4);<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<pre class=\"lang:prisma decode:true\">senao\r\n   imprima(\"Enviado com sucesso para o servidor\");\r\n   erro_msg = socket.escreva( conexao , s  );\r\n<\/pre>\n<p>Caso n\u00e3o haja erro, a frase de sucesso \u00e9 impressa e usamos a fun\u00e7\u00e3o socket.escreva() para escrever no servidor (enviar a mensagem) o texto digitado em s;<\/p>\n<p><strong>Par\u00e2metros:<\/strong><\/p>\n<p>1 &#8211; conexao: a vari\u00e1vel ponteiro da conex\u00e3o realizada com o servidor.<\/p>\n<p>2 &#8211; s : string a ser enviada para o servidor.<\/p>\n<p><strong>Retornos:<\/strong><\/p>\n<p>1 &#8211; erro_msg: string descrevendo erro ou nulo caso n\u00e3o haja erro.<\/p>\n<pre class=\"lang:prisma decode:true\"> se erro_msg entao imprima(erro_msg) fim;\r\nfim<\/pre>\n<p>Tratamento de erro: imprimimos o erro.<\/p>\n<p>fim para fechar o comando &#8216;se conexao == nulo&#8230;<\/p>\n<p><strong>Dicas:<\/strong><\/p>\n<p><em>Para transferir arquivos basta fazer a leitura bin\u00e1ria, obter o conte\u00fado em forma de string, se preferir pode codificar para base64 usando a fun\u00e7\u00e3o string.base64 e assim evitar conflito com caracteres especiais e do lado do servidor \u00e9 s\u00f3 decodificar string.dec_base65(),\u00a0 e salvar em um arquivo com a escrita bin\u00e1ria.<\/em><\/p>\n<p><em><strong>Desafio:<\/strong> crie um programa que seja cliente e servidor simult\u00e2neo para enviar e receber mensagem.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>Prints dos resultados:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2707 size-full\" src=\"https:\/\/linguagemprisma.br4.biz\/blog\/wp-content\/uploads\/2017\/02\/socket_client.png\" alt=\"socket_client\" width=\"511\" height=\"744\" srcset=\"https:\/\/linguagemprisma.br4.biz\/blog\/wp-content\/uploads\/2017\/02\/socket_client.png 511w, https:\/\/linguagemprisma.br4.biz\/blog\/wp-content\/uploads\/2017\/02\/socket_client-206x300.png 206w\" sizes=\"auto, (max-width: 511px) 100vw, 511px\" \/> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2708 size-full\" src=\"https:\/\/linguagemprisma.br4.biz\/blog\/wp-content\/uploads\/2017\/02\/socket_servidor.png\" alt=\"socket_servidor\" width=\"511\" height=\"744\" srcset=\"https:\/\/linguagemprisma.br4.biz\/blog\/wp-content\/uploads\/2017\/02\/socket_servidor.png 511w, https:\/\/linguagemprisma.br4.biz\/blog\/wp-content\/uploads\/2017\/02\/socket_servidor-206x300.png 206w\" sizes=\"auto, (max-width: 511px) 100vw, 511px\" \/><\/p>\n<p><em>At\u00e9 a pr\u00f3xima, vamos ver quem consegue aprimorar e criar um messenger profissional!!!<\/em><\/p>\n<p>Att. Adalberto<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vamos criar um mini messenger, na verdade o esqueleto de um s\u00f3 para ter como base para criar outros. Antes baixe a vers\u00e3o mais atual Prisma, 1.0.99 ou superior. (Testado em Ubuntu 12.04, Mint17, Mint18 e Windows7,10) 1- Servidor Primeiramente, vamos criar o servidor, programa que vai receber as mensagens do cliente. Salve como servidor.prisma,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,7,22],"tags":[],"class_list":["post-2704","post","type-post","status-publish","format-standard","hentry","category-modo_texto","category-prisma","category-rede"],"_links":{"self":[{"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/posts\/2704","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/comments?post=2704"}],"version-history":[{"count":9,"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/posts\/2704\/revisions"}],"predecessor-version":[{"id":2719,"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/posts\/2704\/revisions\/2719"}],"wp:attachment":[{"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/media?parent=2704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/categories?post=2704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/linguagemprisma.br4.biz\/blog\/wp-json\/wp\/v2\/tags?post=2704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}