Lab6 Tiago Porto

aluno: Tiago Porto Barbosa
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 07/12/2008 (2)

Introdução

Os laboratórios 5 e 6 possuem como objetivo desenvolver uma aplicação cliente servidor simples com protocólo próprio.
Neste laboratório 5, implementou-se a parte referente ao servidor da aplicação, feito em Ruby. Utilizou-se conceitos importantes visto no curso como Threads, IO e implementação do padrão Decorator.

Este laboratório é continuação do anterior: Bolão Virtual, e foi desenvolvido a parte "cliente" da aplicação.
Utiliza uma interface gráfica simples feita em Shoes.

"O Shoes é uma ferramenta cross-platform para criação de GUI (interface) para Ruby, desenvolvido pelo Why the lucky stiff (o autor do Poignant guide to Ruby).
Uma das melhores características do Shoes é que ele é fácil de aprender e de usar."

O usuário pode criar e autenticar usuário. Uma vez autenticado, é possivel listar partidas atuais, partidas encerradas, informações detalhadas de uma partida, informações das apostas do usuário, fazer aposta em uma partida e encerrar a conexão

Desenvolvimento

O código do programa usuário foi desenvolvido em um único arquivo.
Com Shoes, foi fácil criar várias telas com diversas funcionalidades em poucos minutos. Porém, a dificuldade era foi entender o funcionamento do TCPSocket e o motivo das variáveis locais perderem os valores.
Para resolver o problema das variáveis perderem seus valores, foram transformadas todas em globais.

require 'initialize'
require 'socket'
require 'yaml'
 
$p = Shoes.app :title => "Lab 6", :width => 220, :height => 310 do
  @@b= background "imagem.png"
  @@b.to_pattern
 
  $w1 =nil
  $w2 =nil
  $w3 =nil
  $w4 =nil
  $w5 =nil
  $w6 =nil
  $w7 =nil
 
  @@flow2 = stack :margin =>10, :width => 200 do
    @@b3 = button "Partidas atuais",  :width => "100%", :margin => 5 do 
 
      @@client.puts "INICIO"
      @@client.puts( 
      {
      "request" =>
        {
        "operation" => "current_matches"      
        }
      }.to_yaml
      )
      @@client.puts "FIM"
      loop do
        string = @@client.gets
        break if string && string.include?("INICIO")
      end
      yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
      yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
      @@response = YAML.load(yaml)
      if Shoes.APPS.include? $w3
        $w3.close
      end
      $w3 = window :title => "Partidas atuais", :width => 270, :height => 350 do
        background "#DFA"
        (@@response[:response]).each do |response|
          stack :margin => 10, :width => 250 do
            background white
            para "Nome: " + response[:name] + "\n" + "Tempo final: " + response[:end_time] + "\n" + "Quantidade de apostas: " + response[:bet_count],  :font => 10
          end
        end
          stack :margin => 10 do
            @@b13 = button "Fechar" do
              close
            end
          end
        end
    end
 
    @@b4 = button "Partidas finalizadas", :width => "100%", :margin => 5 do
      @@client.puts "INICIO"
      @@client.puts( 
      {
      "request" =>
        {
        "operation" => "finalized_matches"      
        }
      }.to_yaml
      )
      @@client.puts "FIM"
      loop do
        string = @@client.gets
        break if string && string.include?("INICIO")
      end
      yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
      yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
      @@response = YAML.load(yaml)
      if Shoes.APPS.include? $w4
        $w4.close
      end
      $w4 = window :title => "Partidas finalizadas", :width => 270, :height => 350 do
        background "#DFA"
        (@@response[:response]).each do |response|
          stack :margin => 10, :width => 250 do
            background white
            para "Nome: " + response[:name] + "\n" + "Tempo final: " + response[:end_time] + "\n" + "Quantidade de apostas: " + response[:bet_count] + "\n" + "Placar final: " + response[:final_score] + "\n" + "Ganhadores: " + response[:winners], :font=>10
            end            
        end
          stack :margin => 10 do
            button "Fechar" do
              close
            end
          end
      end
    end
 
    @@b5 = button "Informações de uma partida", :width => "100%", :margin => 5 do
      #@@client.puts "INICIO"
      #@@client.puts( 
      #{
      #"request" =>
        #{
       # "operation" => "current_matches"      
      #  }
  #    }.to_yaml
 #     )
#      @@client.puts "FIM"
 #     loop do
 #       string = @@client.gets
  #      break if string && string.include?("INICIO")
 #     end
  #    yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
  #    yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
 #     @@response = YAML.load(yaml)
 #     alert @@response
#      @@client.puts "INICIO"
 #     @@client.puts( 
  #    {
  #    "request" =>
    #    {
   #     "operation" => "finalized_matches"      
   #     }
   #   }.to_yaml
   #   )
 #     @@client.puts "FIM"
 #     loop do
  #      string = @@client.gets
  #      break if string && string.include?("INICIO")
  #    end
   #   yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
   #   yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
   #   @@response[:response] << (YAML.load(yaml))[:response]
  #    alert @@response
 
      if Shoes.APPS.include? $w5
        $w5.close
      end
      $w5 = window :title => "Informe de partida", :width =>  270, :height => 350 do
        background "#DFA"
 
        stack :margin => 10 do
          #stack :margin => 5 do
            #alert @@response
            #para "Nome da partida"
            #@lista_de_nomes = []
            #@@response[:response].each {|r| @lista_de_nomes << r[:name]}
            #@@nome_list_box = list_box :items => @lista_de_nomes
          #end
          stack do
            para "Nome da partida"
            @nome_edit_line = edit_line
         end
          flow :margin => 10 do
            button "Verificar" do
              @@client.puts "INICIO"
              @@client.puts( 
              {
              "request" =>
                {
                "operation" => "match_information", 
                "parameters" => @nome_edit_line.text
                }
              }.to_yaml
              )
              @@client.puts "FIM"
              loop do
                string = @@client.gets
                break if string && string.include?("INICIO")
              end
              yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
              yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
              @@response = YAML.load(yaml)
              stack :margin => 10, :width => 250 do
                background white
                para "Nome: " + @@response[:response][:name] + "\n" + "Tempo final: " + @@response[:response][:end_time] + "\n" + "Quantidade de apostas: " + @@response[:response][:bet_count] + "\n" + "Apostadores: " + @@response[:response][:holders] + "\n" + "Finalizada?: " + @@response[:response][:finalized] + "\n" + "Placar final: " + @@response[:response][:final_score] + "\n" + "Ganhadores: " + @@response[:response][:winners], :font => 9
              end
            end
            button "Fechar" do
              close
            end
          end
        end
      end
    end
 
    @@b6= button "Apostar", :width => "100%", :margin => 5 do
      @@client.puts "INICIO"
      @@client.puts( 
      {
      "request" =>
        {
        "operation" => "current_matches"      
        }
      }.to_yaml
      )
      @@client.puts "FIM"
      loop do
        string = @@client.gets
        break if string && string.include?("INICIO")
      end
      yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
      yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
      @@response = YAML.load(yaml)
      if Shoes.APPS.include? $w6
        $w6.close
      end
      $w6 = window :title => "Apostar", :width => 270, :height => 350 do
        background "#DFA"
        stack :margin => 10 do
          stack :margin => 5 do
            para "Nome da partida"
            @lista_de_nomes = []
            @@response[:response].each {|r| @lista_de_nomes << r[:name]}
            @nome_list_box = list_box :items => @lista_de_nomes
          end
          stack :margin => 5,  :width => 50 do
            para "Placar"
            para "Time 1", :font => 9
            @placar1_edit_line = edit_line 
            para "Time 2", :font => 9
            @placar2_edit_line = edit_line
          end
          flow :margin => 10 do
            button "Apostar" do
              @@client.puts "INICIO"
              @@client.puts( 
              {
              "request" =>
                {
                "operation" => "make_bet", 
                "parameters" => [@nome_list_box.text, @placar1_edit_line.text + "x" + @placar2_edit_line.text]
                }
              }.to_yaml
              )
              @@client.puts "FIM"
              loop do
                string = @@client.gets
                break if string && string.include?("INICIO")
              end
              yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
              yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
              @@response = YAML.load(yaml)
              if @@response[:response][:bet_made]
                alert "Feita a aposta"
                close
              else
                alert "Falha ao apostar"
              end
            end
            button "Fechar" do
              close
            end
          end
        end
      end
    end
 
    @@b7 = button "Ver minhas apostas", :width => "100%", :margin => 5 do
      @@client.puts "INICIO"
      @@client.puts( 
      {
      "request" =>
        {
        "operation" => "own_bets_information"      
        }
      }.to_yaml
      )
      @@client.puts "FIM"
      loop do
        string = @@client.gets
        break if string && string.include?("INICIO")
      end
      yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
      yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
      @@response = YAML.load(yaml)
      if Shoes.APPS.include? $w7
        $w7.close
      end
      $w7 = window :title => "Minhas apostas", :width => 270, :height => 350 do
        background "#DFA"
        (@@response[:response]).each do |response|
          stack :margin => 10, :width => 250 do
              background white
              para "Nome: " + response[:name] + "\n" + "Tempo final: " + response[:end_time] + "\n" + "Quantidade de apostas: " + response[:bet_count], :font => 10
          end
        end
          stack :margin => 10 do
            @b4 = button "Fechar" do
              close
            end
          end
      end
    end
 
    @@b8 = button "Fechar conexão", :width => "100%", :margin => 5 do
      @@client.puts "INICIO"
      @@client.puts( 
      {
      "request" =>
        {
        "operation" => "close_connection"      
        }
      }.to_yaml
      )
      @@client.puts "FIM"
      loop do
        string = @@client.gets
        break if string && string.include?("INICIO")
      end
      yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
      yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
      @@response = YAML.load(yaml)
      if !(@@response[:response][:connection])
        Shoes.APPS.each { |s| 
        if s!=$p
          s.close 
        end
        }
        @@flow2.contents.each {|c| c.hide}
        @@flow2.hide
        @@flow1.show
        @@flow1.contents.each {|c| c.show}
        @@client.close
      end
    end
 
  end
  @@flow2.hide
 
  @@flow1 = stack :margin =>10, :width => 200 do
    @@b1= button "Logar" , :margin => 5 do
      if Shoes.APPS.include? $w2
        $w2.close
      end
      if Shoes.APPS.include? $w1
        $w1.close
      end
      $w1 = window :title => "Autenticar", :width => 200, :height => 300 do
        background "#DFA"
        stack :margin => 10, :width => 180 do
          stack :width => "100%" do
            para "Name", :font => "10"
            @nome_edit_line = edit_line :width => "100%"
          end
          stack :width => "100%" do
            para "Senha", :font => "10"
            @senha_edit_line = edit_line :width => "100%"
            @senha_edit_line.style :secret => true
          end
          flow :margin => 10, :width => "100%" do
            button "Logar" do
              @@client = TCPSocket.new('127.0.0.1', 4344)  
              @@client.puts "INICIO"
              @@client.puts( 
              {
              "request" =>
                {
                "operation" => "user_autenticate", 
                "parameters" => [@nome_edit_line.text, @senha_edit_line.text] 
                }
              }.to_yaml
              )
              @@client.puts "FIM"
              loop do
                string = @@client.gets
                break if string && string.include?("INICIO")
              end
              yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
              yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
              @@response = YAML.load(yaml)
              if @@response[:response][:autenticate]
                alert "Autenticado"
                @@nome = @nome_edit_line.text
                @@flow1.contents.each {|c| c.hide}
                @@flow1.hide
                @@flow2.show
                @@flow2.contents.each {|c| c.show}
                close
              else
                alert "Não autenticado"
                @@client.close
              end
            end
            button "Fechar" do
              close
            end
          end
        end
      end      
    end
 
    @@b2 = button "Criar Usuário", :margin => 5 do
      if Shoes.APPS.include? $w1
        $w1.close
      end
      if Shoes.APPS.include? $w2
        $w2.close
      end
      $w2 = window :title => "Registrar", :width => 200, :height => 300 do
        background "#DFA"
        stack :margin => 10, :width => 180 do
          stack :width => "100%" do
            para "Name", :font =>10
            @nome_edit_line = edit_line :width => "100%"
          end
          stack :width => "100%" do
            para "Senha", :font =>10
            @senha_edit_line = edit_line :width => "100%"
            @senha_edit_line.style :secret => true
          end
          flow :margin => 10 do
            button "Criar" do
              @@client = TCPSocket.new('127.0.0.1', 4344)  
              @@client.puts "INICIO"
              @@client.puts( 
              {
              "request" =>
                {
                "operation" => "user_create", 
                "parameters" => [@nome_edit_line.text, @senha_edit_line.text] 
 
                }
              }.to_yaml
              )
              @@client.puts "FIM"
              loop do
                string = @@client.gets
                break if string && string.include?("INICIO")
              end
              yaml = @@client.gets("\nFIM") #depois do INICIO, lê tudo até a palavra FIM
              yaml = yaml.chomp("FIM") #tira o FIM do final do string que foi lido do io
              response = YAML.load(yaml)
              if response[:response][:create]
                alert "Criado"
                @@nome = @nome_edit_line.text
                close
              else
                alert "Não criado"  
                @@client.close
              end
            end
            button "Fechar" do
              close
            end
          end
        end
      end
    end
  end
 
end

Arquivo anexado

ClienteShoes

Conclusão

Foi trivial criar um aplicativo "cliente" do Bolão Virtual com Shoes.
Acho que foi muito importante o conhecimento envolvido na aplicação completa "cliente-servidor".

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License