You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Trabalho final - Desenvolvimento de Sistemas Paralelos e Distribuídos
Integrantes
Guilherme Luiz Lange
Lucas Moraes Schwambach
Mateus Lucas Cruz Brandt
Descrição geral do sistema
O sistema é um serviço para troca de mensagens (chat).
Para utilizar, os usuários precisam criar uma conta. A conta é identificada por usuário e senha, e também é possível informar o nome completo.
Para conversar com outro usuário, é necessário ser amigo dele. Para tanto, um pedido de amizade deve ser enviado e aceito. O outro usuário pode rejeitar o pedido. Até aceitar ou rejeitar, o pedido fica pendente.
O conteúdo das mensagens pode ser texto ou um áudio. O servidor na verdade está preparado para mensagens com qualquer conteúdo binário (áudio, imagem etc.) desde que não muito grande (há mensagens put-file e get-file para, respectivamente, armazenar ou recuperar qualquer arquivo binário). A limitação é no cliente Android que suporta somente áudios no momento.
Requisitos funcionais
RF1: O sistema deverá manter usuários.
RF2: O sistema deverá manter mensagens.
RF3: O sistema deverá manter pedidos de amizade.
RF4: O sistema deverá manter amizades.
RF5: O sistema deverá permitir comunicação entre usuários através de mensagens.
RF6: O sistemá deverá permitir o envio de mensagens de áudio.
Regras de negócio
RN1: Um usuário só pode se comunicar com outro quando for amigo deste.
RN2: Um usuário só se torna amigo de outro quando o primeiro enviar um pedido de amizade e o segundo aceitar esse pedido.
Especificação das mensagens
Toda mensagem é composta por uma sequência de headers, uma linha em branco, e o corpo da mensagem (JSON ou dados binários). Cada header é um par chave-valor separado por um espaço. Os headers que consideramos são os seguintes:
operation: Identificador da operação sendo realizada; obrigatório.
token: Token de acesso. Obrigatório dependendo da request, nem todas precisam.
body-size: Tamanho do corpo em bytes; obrigatório (mesmo que seja 0).
file-extension: Extensão do arquivo (.wav, .png); obrigatório nas requests put-file e get-file.
O sistema permite headers que não sejam esses, mas não faz nada com eles.
Esse é o formato das requests. As respostas segue o mesmo formato, mas os headers são diferentes:
status: Os valores possíveis são ok ou err:<tipo do erro>, onde <tipo do erro> pode ser internal (erro do servidor) ou badRequest (erro do usuário, na request).
body-size: Tamanho do corpo em bytes (sempre presente, mesmo que seja 0).
Apresentamos a seguir a especificação de cada mensagem. A não ser onde outro formato é especificado, presuma que o formato de todos os corpos de request e response são JSON.
Outro detalhe é que qualquer request com corpo JSON pode ter possível retorno o código de erro FAILED_TO_PARSE_JSON, então omitimos na coluna de "possíves erros".
Tipos de dados
Nome
FriendshipStatus
Possíveis valores
"NO_FRIEND_REQUEST": Usuário não é amigo e não existe nenhum pedido de amizade dele ou enviado para ele
"SENT_FRIEND_REQUEST": Usuário não é amigo mas lhe enviou um pedido de amizade
"RECEIVED_FRIEND_REQUEST": Usuário não é amigo mas você enviou um pedido de amizade a ele
"IS_FRIEND": Usuário é amigo
"Meta"-requests
Essas requisições não tem erros possíveis nem requerem corpos.
Operação
Requer token?
Resposta
get-index
Não
Array com os nomes de todas as operações disponíveis. Por exemplo: ["get-index", "get-all-error-codes", "create-user", "edit-user", ...]
Quando uma operação falha e é necessário informar na resposta o que aconteceu, retornamos um código de erro para que o cliente se responsabilize por mostrar como for melhor. De fato, o cliente Android pode mostrar a mensagem em inglês ou português. A seguinte request é um índice desses códigos de erro.
Qualquer operação, quando falhar, retorna um corpo semelhante a {"messageCode": "INCORRECT_CREDENTIALS"}. Os erros retornados assim são informados na coluna "possíveis erros" das especificações das mensagens.
Operação
Requer token?
Resposta
get-all-error-codes
Não
Array com os nomes de todos os error codes retornados. Por exemplo: ["INTERNAL", "FAILED_TO_PARSE_JSON", "INCORRECT_CREDENTIALS", "FAILED_TO_SEND_FRIEND_REQUEST", ...]
Requests para manter usuários
Operação
create-user
Descrição
Cria uma conta para um usuário novo
Requer token?
Não
Request
username Nome do usuário (único)
password Senha
fullname Nome completo
Resposta ok
id ID do usuário criado
Possíveis erros
USERNAME_IN_USE
FAILED_TO_CREATE_USER
Operação
create-session
Descrição
Operação para fazer login do usuário. Cria uma sessão com um token associado, que é retornado para autenticar o usuário em operações posteriores.
Requer token?
Não
Request
username
password
Resposta ok
token Token para ser utilizado no header token para acessos posteriores
id ID do usuário
fullname Nome completo do usuário
Os dois últimos campos retornam os dados do usuário que o cliente não tem (tem somente username e password usados no login) para que tenha os dados completos do usuário.
Possíveis erros
INCORRECT_CREDENTIALS
Operação
edit-user
Descrição
Altera dadaos do usuário
Requer token?
Sim
Request
newFullname Novo nome completo
newPassword Nova senha
Resposta ok
Sem resposta
Possíveis erros
INTERNAL Quando não existe usuário com o ID de usuário associado ao token enviado na request. Indica um bug, não deveria ser possível.
Operação
whoami
Descrição
Retorna os dados completos do usuário logado (exceto senha)
Requer token?
Sim
Request
Sem corpo
Resposta ok
username
fullname
createdAt Timestamp da data de criação do usuário
updatedAt Timestamp da data da última alteração dos dados do usuário (`null` caso nunca)
Possíveis erros
Nenhum
Operação
search-users
Descrição
Busca de usuários. Permite filtrar por nome. Tem paginação.
Requer token?
Sim
Request
query Filtro por nome de usuário
page Os resultados vem paginados (20 por página), então é necessário informar qual página de resultados está sendo visualizada
Resposta ok
A resposta é um array com os dados dos usuários cujos nomes contém a string dada em query. Os dados de cada usuários retornados são os seguintes:
id
username
fullname
friendshipStatus
Possíveis erros
INVALID_PAGE_NUMBER Caso page seja menor que 0.
Operação
end-session
Descrição
Finaliza sessão atual do usuário.
Requer token?
Sim
Request
Sem corpo
Resposta ok
Sem resposta
Possíveis erros
INTERNAL Caso o token enviado não tenha uma sessão correspondente.
Requests para manter amizades
Operação
get-friend-requests
Descrição
Lista pedidos de amizade envolvendo o usuário (enviados por ele ou para ele).
Requer token?
Sim
Request
Sem corpo
Resposta ok
Array de pedidos de amizade, onde cada pedido de amizade é um objeto com os seguintes atributos:
from Objeto representando usuário que enviou o pedido:
id
username
fullname
to Objeto representando o usuário que recebeu o pedido:
id
username
fullname
createdAt Data em que o pedido de amizade foi enviado
Possíveis erros
Nenhum
Operação
send-friend-request
Descrição
Envia pedido de amizade a um outro usuário
Requer token?
Sim
Request
userId ID do usuário a quem o pedido vai ser enviado
Resposta ok
messageCode igual a SENT_FRIEND_REQUEST_SUCCESSFULLY
Possíveis erros
FRIEND_REQUEST_TO_YOURSELF
NO_USER_WITH_GIVEN_ID
YOU_ALREADY_SENT_FRIEND_REQUEST
THEY_ALREADY_SENT_FRIEND_REQUEST
ALREADY_FRIENDS
FAILED_TO_SEND_FRIEND_REQUEST
Operação
finish-friend-request
Descrição
Finaliza (aceita ou rejeita) um pedido de amizade. Ao aceitar, o usuário se torna amigo. Em ambos os casos, o pedido é simplesmente exluído no final.
Requer token?
Sim
Request
senderId ID do usuário que enviou o pedido. Isso serve para identificar o pedido (há no máximo 1 pedido de amizade por par de usuários)
accepted Se o pedido foi aceito ou rejeitado.
Resposta ok
messageCode com mensagem de código FINISHED_FRIEND_REQUEST_SUCCESSFULLY
Possíveis erros
FRIEND_REQUEST_TO_YOURSELF
FRIEND_REQUEST_NOT_FOUND Caso o usuário com id senderId não enviou um pedido de amizade a você.
FAILED_TO_FINISH_FRIEND_REQUEST
Operação
get-friends
Descrição
Retorna lista de amigos do usuário.
Requer token?
Sim
Request
Sem corpo
Resposta ok
Array com os dados dos usuários amigos, onde cada usuário é representado por um objeto com os seguintes atributos:
id
username
fullname
Possíveis erros
Nenhum
Operação
remove-friends
Descrição
Desfaz uma amizade. Os usuários não serão mais amigos e, portanto, não poderão conversar mais. Poderão ainda enviar pedidos de amizade entre si.
Requer token?
Sim
Request
friendId
Resposta ok
Sem corpo
Possíveis erros
Nenhum. Não importa se o usuário nem era amigo em primeiro lugar, o resultado final é o mesmo (não são amigos), então nesse caso não consideramos erro.
Requests para manter arquivos
Operação
put-file
Descrição
Envia um arquivo para ficar armazenado no servidor. Não é uma ação que o usuário vai causar diretamente. Quando ele envia uma mensagem com áudio, primeiro o áudio tem que ser armazenado num arquivo no servidor por meio dessa operação e depois a mensagem tem que ser enviada com uma referência a esse arquivo.
Requer token?
Sim
Request
O corpo é o conteúdo binário do arquivo.
Resposta ok
filename Nome do arquivo no servidor (UUID aleatório). Usado para referenciar na mensagem. Inclui extensão.
Possíveis erros
MISSING_FILE_EXTENSION_HEADER
IO_ERROR
Operação
get-file
Descrição
Busca o conteúdo binário de um arquivo armazenado no servidor.
Requer token?
Sim
Request
filename Nome do arquivo no servidor.
Resposta ok
Conteúdo binário do arquivo.
Possíveis erros
FILE_DOES_NOT_EXIST
IO_ERROR
Requests para manter mensagens
Operação
send-message
Descrição
Envia uma mensagem a um amigo.
Requer token?
Sim
Request
Somente textContents ou fileReference deve estar presente. Ou seja, a mensagem ou contém texto ou contém um arquivo.
to ID do usuário destinatário.
textContents Conteúdo da Mensagem.
fileReference Nome do arquivo.
Resposta ok
id ID da mensagem.
sentAt Timestamp em que a mensagem foi enviada.
Possíveis erros
MALFORMED_MESSAGE Quando não segue a regra de que textContentsoufileReference deve estar presente.
NOT_FRIENDS Quando o usuário destinatário não é amigo de quem enviou.
INTERNAL
Operação
get-messages
Descrição
Busca as mensagens trocadas com um amigo. Não retorna todas, porque seriam muitas, usando paginação no lugar. Mas a paginação também não é por páginas numeradas: deve ser informadas quantas mensagens pegar antes de uma mensagem dada.
Requer token?
Sim
Request
friendId ID do usuário amigo.
before ID da mensagem a partir da qual a busca deve ser feita, incluindo ela.
limit Quantidade de mensagens a trazer.
Resposta ok
Arrary de mensagens trocadas com o amigo, primeiro as mais recentes e depois as mais antigas (ordenadas pelo ID que incrementa monotonicamente).
id ID da mensagem.
userId ID do usuário que enviou a mensagem (você ou o amigo).
sentAt Timestamp em que a mensagem foi enviada.
textContents
fileReference
Possíveis erros
NOT_FRIENDS Quando o usuário informado não é seu amigo.
Requests para receber notificações do servidor
Operação
go-online
Descrição
Inicia uma conexão com o servidor por onde ele envia notificações de atualizações (usuário ficou online/offline, usuário enviou mensagem).Essa conexão é mantida pelo socket com que a request foi feita, que é mantido aberto.
Requer token?
Sim
Request
Sem corpo
Resposta ok
Corpo vazio, mas eventualmente envia mensagens de notificação. Todas as mensagens são compostas pelo número de bytes no corpo e pelo corpo, em sequência, sem espaços no meio. O corpo vem em formato JSON. Sempre há um campo type descrevendo o tipo da mensagem. Os valores possíveis são user-online, user-offline, chat-message-received e ping. A mensagem de tipo ping serve para que o servidor detecte quando usuários ficam offline - se o cliente não responder com a string pong a tempo, o servidor desliga a conexão.
Possíveis erros
Sem erros possívels
Operação
go-offline
Descrição
Fecha uma conexão de notificações com o servidor (conexão aberta previamente com go-online). A request não precisa ser enviada com o mesmo socket utilizado para enviar a go-online.
Requer token?
Sim
Request
Sem corpo
Resposta ok
Sem corpo
Possíveis erros
Sem erros possívels
Operação
get-online-users
Descrição
Recebe lista completa dos IDs dos usuários que atualmente estão online. Para que o cliente mantenha a lista de usuários atualmente online atualizadas, primeira envia essa request para receber uma lista inicial, e ao longo do tempo recebe notificações de usuários que ficaram online ou offline pela conexão aberta pela request de go-online.