domingo, 5 de abril de 2015

Hardcore Devel #11 - Comunicações de rede.

Continuamos aqui o nosso diário de bordo de desenvolvimento. E hoje estaremos falando novamente do projeto MinArena que recebeu correção de bugs e será colocado em um teste físico em breve. Vamos falar um pouco sobre redes aqui, para que se entenda o que será feito.

Ainda temos outros projetos que estão no forno cozinhando, porém a prioridade está neste projeto que já está quase no pronto. Então temos que preparar os molhos, e fazer aquilo que os Chefs não podem fazer. Provar a coisa.

Bom, vamos recapitular nosso conhecimento de jogos online. O maior problema desse tipo de jogo é a sincronização e a comunicação entre as máquinas. Se você tem acompanhado esse diário você já sabe disso. Hoje vamos destrinchar um pouco isso.

A rede de computadores tem um sério problema, ela funciona como uma ponte de um veículo só, onde tem gente passando para os dois lados, então dá pra ter uma noção da confusão que isso causa. Você pode considerar os roteadores espalhados pelo mundo como os pontos onde as pessoas esperam para atravessar a ponte junto com um guardinha que fala quem vai passar em cada instante.

Só que a coisa fica complicada porque esses guardinhas podem explodir carros a qualquer momento se esses pontos de espera(filas) ficarem muito cheias. Ou seja, aquele mensageiro que o seu programa mandou pode não conseguir chegar no destino final! O que fazer então?

Fazemos aquilo que nós seres humanos somos bons em fazer: Pertubar.

Manda logo 50 mensageiros de uma vez. Alguém vai ter que chegar lá. Se você manda uma mesma mensagem muitas vezes, maior a chance de ela chegar no seu destinatário final. Por favor, não faça isso com as cartas que você põe no correio.

Isso gera um outro problema, que é aquilo que nós brasileiros enfrentamos todos os dias: O congestionamento.

Sim! A rede de computadores congestiona. Pra falar a verdade, ela vive congestionada. Você deve sentir isso na prática na sua própria casa onde várias pessoas compartilham uma mesma conexão de internet. Todos essas pessoas que usam a mesma rede, muito provavelmente, usam a mesma porta de saída. Isso gera aquele gargalo que faz com que os carros também congestionem. E isso é ruim para toda as pessoas que estão usando aquela rede específica.

Mas e se você soubesse quando a sua mensagem chegou lá? Daí você não precisaria mandar 50 mensageiros, vai mandando conforme for necessário.

O problema é, pra você saber que a mensagem já chegou, o receptor tem que te avisar. E para isso acontecer ele tem que mandar uma mensagem de volta respondendo que a sua chegou. Adivinha só: A resposta faz o caminho inverso da primeira mensagem, ou seja, você precisa usar o próprio recurso para evitar que você use o recurso demais. Consegue perceber o problema?

Bom, eles criaram o TCP, que é um protocolo pra transmissão de mensagens pela internet que faz isso tudo pra você sem que você possa perceber. Manda mensagem, recebe resposta, mede tempo, e a coisa toda, mas nós já sabemos que ele tem a desvantagem de ser inútil para aplicações de tempo real. E como ele trafega pelo mesmo lugar que o TCP, adivinhem só, congestionamento.

Então nós notamos que precisariamos disso no projeto e não poderíamos simplesmente evitar isso. Testamos fazendo super lotação da rede e basicamente derrubamos as conexões das outras pessoas da casa.

A brincadeira é simples, Escolha um intervalo de tempo para você repetir as mensagens, repita até um determinado limite de vezes ou até chegar uma respostas do destinatário. Vamos colocar bonitinho assim
  1. thresh := 100ms
  2. recebido := false
  3. t0 := tempo atual
  4. t1 := tempo atual
  5. t2 := tempo atual
  6. Envia_pacote()
  7. Se(pacote_recebido())
  8.     recebido := true
  9. Fim Se
  10. Enquanto(t1 - t0 > thresh  && !recebido)
  11.     Se pacote_recebido()
  12.         recebido := true
  13.     t1 := tempo atual
  14.     Se(t2 - t1 > 20ms)
  15.         Envia_Pacote()
  16.         t2 := + 20ms
  17. Fim Enquanto
Pronto, colocamos uma rotina de espera de mensagem em forma de metacódigo. Isso deve bastar para dar uma inspiração. Note que eu abstraí o processo de verificação de pacotes, e estou supondo que "pacote_recebido()" vai resolver esse problema para mim. Note também que Envia_Pacote() também abstraí a forma como se envia um pacote.

Note também que eu usei uma notação relativamente comum. Usando ":=" para detonar uma variável recebendo um valor, "&&" para detonar um operador lógico AND, e Se e Enquanto como estruturas de controle pra fazer condicionais e loop.

Estamos quase em fase de testes! Continuem ligados!

Nenhum comentário:

Postar um comentário