Última Atualização: 08 de Dezembro de 2001, 22:27 BRDT

Troca de mensagens

Formato das mensagens

Uma mensagem (br.shmem.Message) pode ter os seguintes elementos:

Tipos de Mensagem

  1. Cliente-Servidor: mensagens trocadas entre servidor e clientes podem ser:
    1. LOGIN - referente ao processo de cadastro no servidor.
    2. LOGOUT - quando um cliente abandona o acesso ao servidor
    3. SHARE - para incluir um objeto no espaço global
    4. UNSHARE - para remover um objeto do espaço global
    5. REQUEST - para pedir o dono de um objeto no espaço global
    6. VALIDATE - para verificar a validade da cópia local
    7. BEGIN_TRANS - para pedir o direito de escrita em um objeto global
    8. COMMIT - inicia o processo de tornar permanente uma alteração
    9. ROLLBACK - para descartar as mudanças feitas durante a escrita.
    10. UNLOCK - enviada pelo dono de um objeto para liberar o lock de escrita do mesmo.
    11. IDENTIFY - enviada pelo cliente para identificar um host que se conecta a ele.
    12. UPDATE - enviada pelo servidor para indicar que um escritor iniciou o processo de commit.
    13. PING - enviada pelo servidor para verificar se um cliente está ativo.
  2. Cliente-Cliente: mensagens trocadas entre clientes podem ser:
    1. GET - requisita uma cópia de um objeto ao seu dono.
    2. RELOAD - quando o dono de um objeto requisita a cópia modificada ao escritor.

Nota sobre a implementação

Algumas funcionalidades implementadas na troca de mensagens não são utilizadas nas camadas superiores, por exemplo, o PING. Veja coisas por fazer para maiores detalhes.

Mensagens trocadas em cada operação

Na tabela a seguir, o flag de erro foi trocado por sufixos _OK e _ERROR no tipo da mensagem.
 
Mensagem Resposta
Login
Nessa iteração são trocadas as chaves públicas do cliente e do servidor.

C->S: (LOGIN, novo cliente)
1) S->C: (LOGIN_OK, server Id)
2) S->C: (LOGIN_ERROR, "already logged in")
Logout
O servidor limpa as entradas do cliente

C->S: (LOGOUT)
1) S->C: (LOGOUT_OK)
2) S->C: (LOGOUT_ERROR, "not logged in.")
Share
O cliente publica o objeto "brasil.frutas.Banana"

C->S: (SHARE, "brasil.frutas.Banana")
1) S->C: (SHARE_OK, stamp1)
2) S->C: (SHARE_ERROR, "brasil.frutas.Banana", "brasil.frutas.Banana is already shared.")
Unshare
O cliente remove o objeto "brasil.frutas.Banana"

C->S: (UNSHARE, "brasil.frutas.Banana")
1) S->C: (UNSHARE_OK)
2) S->C: (UNSHARE_ERROR, "brasil.frutas.Banana", "object is not shared")
3) S->C: (UNSHARE_ERROR, "brasil.frutas.Banana", "you are not the owner of brasil.frutas.Banana.")
Request
O cliente C1 pede uma cópia de Banana, que está com o cliente C2.

C1->S: (REQUEST, "brasil.frutas.Banana")
1) S->C1: (REQUEST_OK, C2)

2) S->C1: (REQUEST_ERROR, "brasil.frutas.Banana","object is not shared")
Reload
C1 pede Banana para C2:

C1->C2: (RELOAD, "brasil.frutas.Banana")
1) C2->C1: (RELOAD_OK, brasil.frutas.Banana)
2) C2->C1: (RELOAD_ERROR, "brasil.frutas.Banana", "object is not shared")
Validate
O cliente C1verifica sua cópia de Banana. No primeiro caso, a cópia é válida, e no segundo, antiga.

C1->S: (VALIDATE, "brasil.frutas.Banana", stamp1)
1) S->C: (VALIDATE_OK)
2) S->C: (VALIDATE_OK, C2)
3) S->C1: (VALIDATE_ERROR, "brasil.frutas.Banana", "object is not shared"
4) S->C1: (VALIDATE_ERROR, "brasil.frutas.Banana", "timestamp signature check failed."
BeginTrans
C1 pede direitos de escrita em Banana. A resposta (3) não foi implementada nesta versão.

C1->S: (BEGIN_TRANS, "brasil.frutas.Banana")
1) S->C1: (BEGIN_TRANS_OK, stamp1, C2)
2) S->C1: (BEGIN_TRANS_ERROR, "brasil.frutas.Banana", "already locked")
3*) S->C1: (BEGIN_TRANS_ERROR, "brasil.frutas.Banana", "you don't have permission to lock brasil.frutas.Banana.")
Commit
C1 inicia a primeira etapa do commit: pedir ao servidor um novo TimeStamp para o objeto modificado, e também um host para quem mandá-lo:

C1->S: (COMMIT, "brasil.frutas.Banana")
1) S->C1: (COMMIT_OK, stamp2, C2)
2) S->C1: (COMMIT_ERROR, "brasil.frutas.Banana", "you don't have the lock")
3) S->C1: (COMMIT_ERROR, "brasil.frutas.Banana", "owner not found, may have logged out.")
Update
O servidor conclue a primeira etapa do commit: avisa C2 que um commit foi realizado:

S->C2: (UPDATE, "brasil.frutas.Banana")
Não há resposta. C2 envia um GET a C1.
Get
C2 inicia a segunda etapa do commit: pegar de C1 o objeto modificado:

C1->C2: (GET, "brasil.frutas.Banana", brasil.frutas.Banana, stamp2 )
1) C2->C1: (GET_OK, brasil.frutas.Banana)
2) C2->C1: (GET_ERROR, "brasil.frutas.Banana", "object is not shared")
Unlock
A segunda etapa do commit termina quando C2 libera o lock de escrita no servidor:

C2->S: (UNLOCK, "brasil.frutas.Banana", stamp2)
1) S->C2: (UNLOCK_OK)
2) S->C2: (UNLOCK_ERROR, "brasil.frutas.Banana", "object is not shared"))
3) S->C2: (UNLOCK_ERROR, "brasil.frutas.Banana", "invalid timestamp"))
4) S->C2: (UNLOCK_ERROR, "brasil.frutas.Banana", "object is not locked"))
Rollback
C1 descarta mudanças. A operação também libera o lock de escrita.

C1->S: (ROLLBACK, "brasil.frutas.Banana")
S->C1: (ROLLBACK_OK)
S->C1: (ROLLBACK_ERROR, "brasil.frutas.Banana", "you don't have the lock")
Ping
Servidor verifica se o cliente está acessível. Como a mensagem é enviada por TCP, a simples conexão é suficiente para um resultado positivo.

S->C: (PING)
Não há resposta.