Skip to content

Latest commit

 

History

History
11 lines (9 loc) · 26.5 KB

README.md

File metadata and controls

11 lines (9 loc) · 26.5 KB

Chat para aula de Sistemas Distribuídos - FATEC Carapicuiba - Prof. Luquini - 2015

Links para projetos de outros alunos

Especificação

1. Geral

1.1 Sobre

A inspiração para esse modelo foi encontrada nas salas de bate-papo muito utilizadas na década de 90. Uma diferença fundamental em relação ao modelo original é que o protocolo é desenvolvido com base em uma arquitetura P2P, o que leva à diferenças fundamentais em seu funcionamento.

1.2 Funcionalidades

  • Usuários identificados por nome
  • Aviso quando usuário entra ou sai da sala
  • Envio de mensagens globais (para toda à lista)
  • Envio de mensagens privadas (um usuário selecionado)
  • Timestamp(“hh:mm:ss” - hora:min:seg) nas mensagens

1.3 Exemplo de funcionamento

13:01:45 Vader entra na sala

13:02:05 Vader diz a todos: Saudações!

13:02:59 Yoda diz a Vader: Não o vejo, muito tempo faz!

13:02:59 Vader sussurra para Luke: Fico feliz em vê-lo...

1.4 Princípio de funcionamento

Para que os usuários sejam identificados, é necessário que se mantenha uma lista de todos que estão no chat em um dado momento. Como não há um servidor central, a solução adotada é que cada usuário mantenha uma lista atualizada de participantes. Essa lista deve conter a relação do ip e o nickname de cada usuário, além de uma timestamp que indica quando foi a última atividade recebida desse usuário.

Com essa lista, cada aplicação será responsável por gerar as mensagens de forma amigável, contendo o nickname do usuário que enviou, qual a ação executada e a mensagem em si.

O protocolo define parâmetros que são enviados no corpo da mensagem, porém, nem todos esses parâmetros são exibidos na tela. A mensagem, em sua forma completa, serve para indicar à aplicação final o que deve ser impresso na tela, assim como serve também para manutenção da lista de usuários.

2. Modelo de comunicação

2.1 Formato

As mensagens serão trocadas dentro do formato JSON, devido à este ser um formato simples e também à existencia de parsers para este formato em todas as linguagens modernas. Segue um exemplo de mensagem:

{

   “target”:”192.168.0.125”,

   “action”:“say”,

   “content”: “Olá!“

}

Os parâmetros contidos na mensagem variam de acordo à ação(action) desejada. Deve se considerar o nome dos parâmetros e conteúdo do parâmetro “action” como case-sensitive.

Listagem de ações possíveis:

  • search: mensagem em broadcast para buscar usuários
  • keepAlive: informa as demais usuários quem está ativo, troca a lista de usuários
  • say: mensagem de tipo aberto, pode ser lida por todos
  • whisper: mensagem restrita a um usuário
  • leave: indica que o usuário saiu da sala
  • report: informa à um usuário um erro de comunicação

2.2 Detalhamento das Ações:

Search:

Tem por objetivo encontrar usuários ativos. É a primeira ação a ser executada ao iniciar o programa, e deve se repetida a cada 2 segundos até se obter uma resposta.

Modo de envio: broadcast

Parâmetro: action, nickname

Modelo:

{

   “action”:“search”,

   “nickname”: “Luke”

}

KeepAlive:

Essa ação deve ser enviada em resposta de qualquer ação Search que seja recebida, indicando assim ao usuário ingressante quem está na sala. Além disso, ela deve ser enviada a cada 10 segundos para indicar que o usuário continua ativo. A informações sobre o emissor do keepAlive é utilizada para dar manutenção na lista de usuários que estão ativos, se o usuário deixar de enviar o keepAlive, ele será removido da lista dos usuários ativos. A infoprmações sobre os usuários contida na mensagem de keepAlive é usada somente para inclusão de usuários que ainda não estã na lista do receptor. Essa lista não deve ser utilizada para exclusão dos usuários.

Ver item 4 para mais detalhes sobre ações que alteram a lista de usuários.

Modo de envio: multicast

Parâmetro: action, nickname

Modelo:

{

   “action”:“keepAlive”,

   “nickname”: “Vader“,

   “users” : [

       {“nickname”:”Luke”, “address”:“192.168.0.1”},

       {“nickname”:”Yoda”, “address”:“192.168.0.4”},

       {“nickname”:”R2D2”, “address”:“192.168.0.6”}

    ]

}

Say:

Envia uma mensagem à um usuário específico ou a todo o grupo. Note que essa mensagem não é oculta: todos podem ler o que foi enviado. O parâmetro target serve unicamente para endereçar a mensagem, e, quando ausente, indica que a mensagem foi direcionada à todos da sala.

Modo de envio: multicast

Parâmetros obrigatórios: action, value

Modelo:

{

   “target”:”192.168.0.125”,

   “action”:“say”,

   “content”: “Olá!“

}

Whisper:

Envia uma mensagem à um usuário específico de forma oculta. Essa mensagem não deve ser enviada por multicast para que outros usuários não tenham acesso à ela. O parâmetro content carrega o conteúdo da mensagem.

Modo de envio: direcionado à um ip

Parâmetros obrigatórios: action, value

Modelo:

{

   “action”:“whisper”,

   “content”: “Olá, josé, como vai?“

}

Leave:

Indica que o usuário saiu da sala.

Parâmetros obrigatórios: action

Modo de envio: multicast

Modelo:

{

   “action”:“leave”,

}

Report:

Indica que à um usuário que houve um erro de comunicação. Deve ser enviada automaticamente em caso de um JSON mal formado, ou de uma action com parâmetros obrigatórios ausentes.

Parâmetros obrigatórios: action, message

Modo de envio: direcionado à um ip

Modelo:

{

   “action”:“report”,

   “message”: “JSON parse error”

}

3. Sequência da aplicação

  1. Inicia-se a procura de usuários através do comando Search
  1. Caso não recebe nenhuma resposta, deve repetir a ação numa frequência de 2 segundos
  2. Receberá a resposta dos demais usuários através da ação keepAlive. Para cada resposta recebida, deve adicionar o endereço e nickname do usuário à sua lista
  1. O usuário encontra-se estabelecido no ambiente de chat
  1. Pode então realizar as ações de conversa (Say e Whisper)
  2. Deve utilizar a ação Search à cada 10 segundos para confirmar os usuários ativos. Caso existam respostas de usuários que não foram previamente identificados, estes devem ser adicionados à lista.
  3. Caso todos os usuários saiam da sala, deve voltar ao passo I
  1. Para sair da sala, deve informar os demais usuários com a ação Leave
  1. Ao receber a ação Leave de um terceiro, deve-se remover esse usuário da lista de usuários

4. Sistema de impressão de mensagens

4.1 Geral

Nem todas as ações que trafegam pelo sistema são exibidas aos usuários finais. Além de filtrar apenas o que é relevante ao usuário, também é necessário formatar as mensagens de forma que o chat se torne amigável e agradável. Seguem as especificações de como filtrar e formatar o conteúdo à ser exibido.

4.2 Detalhamento de impressão para cada ação

Search

  1. Quando se está à ingressar na aplicação, à procura de usuários:

        Envia: {“action”:”search”, “nickname”:”Luke”}

        Imprime: Procurando usuários ativos…

  1. Quando se recebe uma mensagem de search de um novo usuário:

        Recebe: {“action”:”search”, “nickname”:”Vader”}

        Imprime: Vader entrou na sala…

KeepAlive

  1. Quando se recebe de um usuário não identificado:

        Recebe: {“action”:”keepAlive”, “nickname”:”Vader” }

        Impressão: Vader entrou na sala.

  1. Quando se recebe de um usuário previamente identificado:

Recebe: {“action”:”keepAlive”, “nickname”:”Vader”}

        Impressão: [Não há impressão]

        

  1. Quando um usuário conhecido não responde por 10 segundos

Impressão: Vader está ausente...

        

Say

  1. Quando possui parâmetro target:

        Recebe: {“action”:”say”, “target”:”192.168.0.3”, “content”: “Saudações!”}

        Impressão: Vader diz à R2D2: Saudações!

  1. Quando não possui o parâmetro target:

        Recebe: {“action”:”say”,  “content”: “Saudações!”}

        Impressão: Vader diz à todos: Saudações!

Whisper

        Recebe: {“action”:”whisper”,  “content”: “Eu sou seu pai!”}

        Impressão: Vader sussurra à Luke: Eu sou seu pai!

Leave

        Recebe: {“action”:”leave”}

        Impressão: Vader saiu da sala.

Report

        Recebe: {“action”:”report”, “message”:”JSON parse error”}

        Impressão: Vader reportou um erro: JSON parse error

4. Manutenção da lista de usuários

4.1 Entidade Usuário

Um usuário precisa ser mantido na lista com 4 informações básicas:

  1. Nickname: nome amigável do usuário, informado através das ações search ou keepAlive
  2. Address: endereço de IP do usuário. Note que esse endereço nunca é informado em uma ação, ele é obtido pela aplicação através da identificação do IP de origem de uma mensagem.
  3. Timestamp: Última mensagem de keepAlive ou search recebida desse usuário

4.2 Exemplo de lista de usuários

A lista será apresentada em JSON apenas para facilitar o entendimento. Ela será implementada de acordo à linguagem escolhida.

{

{“address”: 192.168.0.2, “nickname”:”Vader”, “timestamp”:1447470110},

{“address”: 192.168.0.3, “nickname”:”Yoda”, “timestamp”:1447470103},

{“address”: 192.168.0.13, “nickname”:”R2D2”, “timestamp”:144746080},

}

4.3 Ações que alteram a lista de usuários

  1. Ao executar uma ação de search: cada resposta keepAlive recebida deve adicionar o usuário à lista
  2. Ao receber uma ação search de um novo usuário: deve se adicionar o usuário à lista
  3. Ao receber uma ação leave de um usuário: deve se remover o usuário da lista
  4. Ao enviar ou receber uma ação de keepAlive para verificar se usuários permanecem ativos: ver detalhes no próximo ponto (4.4)

4.4 Ação keepAlive para manutenção da lista

A ação keepAlive deve ser repetida à cada 10 segundos para verificar se os usuários permanecem ativos. A lista de usuários deve ser enviada para que os sejam identificados usuários que, por motivos de falha de comunicação, não tenha tenham respondido à ação de search inicial. Segue o fluxo de como essa ação deve ser repetida:

  1. Verifica-se as timestamps e atualiza-se os status de todos os usuários
  2. Envia-se a ação como multicast a cada 10 segundos
  3. Aguarda-se keepAlive de todos os usuários
  1. Caso seja encontrado algum usuário novo nas listas trocadas, esse deve ser adicionado à lista
  1. Para toda ação keepAlive recebida, deve-se atualizar o timestamp desse usuário
  2. Um usuário que permanecer mais de 60 segundos ausente deve ser eliminado da lista

5. Fluxo de excessões

Esse protocolo se baseia no princípio de confiabilidade nas mensagens trocadas. Não existe formas de validar se os programas-cliente realmente estão agindo de acordo à mensagem enviada (um usuário pode enviar uma ação Leave e se manter na sala, por exemplo).

O tratamento de erros proposto é apenas para mensagens incompletas, nas quais algum parâmetro obrigatório está ausente. Nesse caso, essa mensagem deve ser descartada, sem nenhum resultado no chat e nem na lista de usuários. O usuário que enviou a mensagem com erros deve ser informado através da ação Report.

Note que todo parâmetro ausente deve ser considerado como vazio, de forma que uma mensagem com a ação “Say” que não possua o parâmetro target deve ser direcionada à toda sala.

6. Configurações padrão

Porta: 9000

Frequência de envio de search (quando a lista de usuários está vazia): 2 segundos

Frequência de envio de keepAlive: 10 segundos

Formato de timestamp na janela de chat: hh:mm:ss