O surgimento de com (a seguir denominado DCOM nos oferece a oportunidade de criar facilmente aplicativos distribuídos; Aplicativos, desenvolvedores quase podem ignorar o MS-RPC) e desenvolver funções poderosas e acoplamento baixo (os módulos funcionais são relativamente independentes, Ele fez bom uso das idéias da OO) e é fácil de implantar o sistema de computação distribuído.
Neste artigo, pretendemos usar a DCOM para desenvolver uma sala de bate -papo da LAN, não apenas como uma pesquisa técnica, mas na verdade acredito que essa também deve ser uma ferramenta útil. Primeiro de tudo, precisamos ter um entendimento geral das funções desta sala de bate -papo:
1. Pelo menos essa sala de bate -papo deve permitir que vários usuários da LAN conversem.
2. Deve haver salas de sub-chat com vários tópicos, e os usuários podem optar por entrar em uma sala de bate-papo para conversar.
3. O cliente deve ser o mais simples possível (sem configurar o DCOM), e um lado do servidor precisa gerenciar todos os comportamentos de interação, gerenciar o número de salas de bate -papo e configurações relacionadas e fazer um bom trabalho no monitoramento e registro do sistema.
4. Expanda as funções da sala de bate -papo (como funções de conversa tranquila, emojis, etc.). Com base na descrição funcional acima, depois de analisar cuidadosamente o problema, projetamos o seguinte esboço:
Neste artigo, queremos implementar aproximadamente um núcleo básico deste programa, incluindo IchatManager, TchatroomManager e Tchatroom, para concluir o servidor com as funções mais básicas e executar uma detecção simples de clientes. Nosso foco está no lado do servidor, porque implementará a maioria das funções da sala de bate -papo, e o cliente é apenas um programa muito pequeno e simples.
Devido ao espaço, listamos apenas o código para peças importantes. Primeiro, vamos dar uma olhada na aparência da nossa interface IchatManager:
Ichatmanager = interface (idispatch)
['{E7cd7f0d-447f-497a-8c7b-1d80e748b67f}']
Procedimento SpeakTO (const Content: WideString; Destid: Inteiro);
// O cliente fala da sala designada, e o destino é o número da sala
Função ReadFrom (SourceID: Inteiro): ISTRINGS;
// O cliente lê o conteúdo da conversa da sala designada, o fonte é o número da sala
function ReadReady (ID: Inteiro): byte;
// O cliente pode verificar se a sala especificada já pode ler o conteúdo da conversa
Procedimento ConnectRoom (Nome de usuário const: WideString; RoomID: Inteiro);
// O cliente faz login em salas designadas
Procedimento desconectado (nome de usuário const: wideString; RoomID: Inteiro);
// o cliente sai da sala designada
Função TestClearBufferTag (RoomID: Inteiro): Inteiro;
// Testes de cliente se a zona de buffer da sala especificada é limpa ou não
fim;
Vamos dar uma olhada na seção TchatManager da classe de implementação da interface:
tipo
TchatManager = classe (TautoObject, IchatManager)
protegido
Função ReadFrom (SourceID: Inteiro): ISTRINGS;
// Aqui usamos os tstings complexos do tipo estendido por Delphi, a fim de fazer com que o compor
// tipo, Delphi fornece interface de isttrings
Procedimento SpeakTO (const Content: WideString; Destid: Inteiro);
function ReadReady (ID: Inteiro): byte;
// usado para fornecer ao cliente a consulta se a sala especificada é legível e se o buffer da sala especificado está vazio
Procedimento Connectroom (Const Username: WideString; RoomID: Integer);
SafeCall;
Procedimento desconexão (nome de usuário const: wideString; RoomID: Integer);
SafeCall;
Função TestClearBufferTag (RoomID: Inteiro): Inteiro;
fim;
Parte da implementação:
var
TEMPROON: Tchatroom;
Começar
TEMPROOM: = ChatroomManager.FindroomById (SourceID);
enquanto temprom.locked faz
Começar
// não faz nada está apenas esperando para ser desbloqueado
fim;
GetOLestrings (temprom.onead, resultado);
fim;
procedimento tchatmanager.speakto (const Content: wideString; destino: inteiro);
var
TEMPROON: Tchatroom;
Começar
TEMPROOM: = ChatroomManager.findroombyId (Destid);
enquanto temprom.locked faz
Começar
// não faz nada está apenas esperando para ser desbloqueado
fim;
Temprom.onespeak (conteúdo);
fim;
function tchatManager.readReady (id: inteiro): byte;
var
TEMPROON: Tchatroom;
Começar
TEMPROOM: = ChatroomManager.findroomById (ID);
Se temProom.CanRead, o resultado: = 1 else Resultados: = 0;
fim;
procedimento tchatManager.Connetrom (const Username: wideString;
Roomid: Inteiro);
// O cliente faz login na sala especificada através da interface e não está totalmente implementada
var
TEMPROON: Tchatroom;
Começar
TEMPROOM: = ChatroomManager.findroombyId (RoomID);
Temprom.loginroom (nome de usuário);
fim;
Procedimento tchatManager.disconnetrom (const UserNeN: wideString;
Roomid: Inteiro);
// O cliente sai da sala especificada através da interface e não está totalmente implementada
var
TEMPROON: Tchatroom;
Começar
TEMPROOM: = ChatroomManager.findroombyId (RoomID);
Temprom.leaveroom (nome de usuário);
fim;
function tchatManager.testclearBufferTag (RoomID: Integer): Inteiro;
var
TEMPROON: Tchatroom;
Começar
TEMPROOM: = ChatroomManager.findroombyId (RoomID);
Resultado: = TemProom.clearBufferTag;
fim;
Inicialização
TautoObjectFactory.Create (ComServer, TchatManager, Class_ChatManager,
cimultiInstance, tmapartment);
fim.
O Tchatroom mais importante se parece:
tipo
Tchatroom = classe
Privado
FBuffer: Array [1..20] de String;
Comprimento do fBuffer: número inteiro;
FroomName: String;
Froomid: Inteiro;
Flocked: Boolean; // Lock Síncrono, usado para lidar com a situação em que várias pessoas enviam conversas ao mesmo tempo
FConnectCount: Inteiro; // O número atual de pessoas na sala
FclearBufferTag: Inteiro;
// Este valor saltará uma vez que sempre que o buffer for limpo, e esse pulso é detectado pelo cliente
protegido
procedimento clearbuffer; // limpe o buffer
função getCanRead: boolean;
público
Construtor Create (RoomName: String; RoomID: Integer);
Procedimento Onespeak (conteúdo: string); // Adicione um conteúdo de bate -papo ao buffer
Procedimento Loginroom (Nome de usuário: String); // Consulte a parte da implementação dos comentários
Procedimento Colherom (Nome de usuário: String); // Consulte a parte da implementação dos comentários
função OneRead: tStrings; // Leia o registro do buffer
Propriedade bloqueada: Boolean Read Flocked;
Propriedade CANRELADO: Boolean Read GetCanRead; // Determine se o buffer está vazio, caso contrário, é ilegível
Propriedade ClearBufferTag: Inteiro Leia FclearBufferTag;
fim;
Implementação de Tchatroom:
{Tchatroom}
construtor tchatroom.create (nome da sala: string; Roomid: Integer);
Começar
Comprimento do fBuffer: = 0;
FconnectCount: = 0;
FclearBufferTag: = 1;
Reunido: = false;
FroomName: = RoomName;
FROOMID: = Roomid;
fim;
procedimento tchatroom.clearbuffer;
var
I: Inteiro;
Começar
/// Aqui você pode detectar um sinalizador para determinar se o servidor precisa gravar cada conteúdo de bate -papo.
para i: = 1 a 20 faça
FBuffer [i]: = '';
Comprimento do fBuffer: = 0;
FclearBufferTag: = 0-fclearBufferTag;
fim;
procedimento tchatroom.onespeak (conteúdo: string);
Começar
Reunido: = true;
Inc (comprimento do FBuffer);
Se fBufferLength> 20 então
Começar
ClearBuffer;
Inc (comprimento do FBuffer);
fim;
FBuffer [fBufferLength]: = content;
Reunido: = false;
fim;
function tchatroom.onead: tStrings;
var
FSTRINGS: TSTRINGS;
I: Inteiro;
Começar
Reunido: = true;
FStrings: = tStringList.create;
para i: = 1 para o comprimento
FStrings.add (fBuffer [i]);
resultado: = fStrings;
Reunido: = false;
fim;
function tchatroom.getCanRead: boolean;
Começar
resultado: = false;
Se fBufferLength> 0, resultado: = true;
fim;
procedimento tchatroom.loginroom (nome de usuário: string);
// O evento da sala de bate -papo de login do usuário não está totalmente implementado aqui
Começar
Inc (fConnectCount);
fim;
procedimento tchatroom.leaveroom (nome de usuário: string);
// O usuário sai do evento da sala de bate -papo, ele não está totalmente implementado aqui
Começar
DEC (fConnectCount);
fim;
A última parte importante do servidor TchatroomManager:
tipo
TchatroomManager = classe
Privado
Sala de chat: matriz de tchatroom;
público
construtor Criar;
Função FindroombyId (ID: Inteiro): Tchatroom;
fim;
Parte da implementação:
{Tchatroommanager}
construtor tchatroommanager.create;
var
I, BOLECOUNT: INTEGER;
Nomes de quartos: tStrings; // nome da sala é o nome da sala de bate -papo no arquivo de configuração
Começar
RoomCount: = 1;
// Aqui, leremos várias salas de bate -papo do arquivo de configuração.
Nomes de quartos: = tStringList.create;
RoomNames.add ('Testroom'); // Esta frase será substituída pela leitura final do arquivo de configuração.
SetLength (sala de chat, contador de quarto);
para i: = 1 para a base de sala
Chatroom [i]: = tchatroom.create (nomes de quartos [i-1], i);
fim;
função tchatroommanager.findroombyId (id: inteiro): tchatroom;
// Esta função é chamada pela interface IchatManager, uma vez que a versão final da interface será fornecida ao cliente
// A função de obter a lista de quartos é para que o cliente conheça o ID de sua sala
Começar
Resultado: = Chatroom [id];
fim;
Inicialização
ChatroomManager: = tchatroomManager.create;
fim.
Depois que a parte principal do lado do servidor é concluída, configuramos a configuração DCOM do lado do servidor e podemos desenvolver um cliente simples para testar: (embora o cliente seja o mais simples possível, não precisamos configurar o DCOM, mas ainda Precisa copiar o tipo de servidor, o arquivo da biblioteca .tlb só pode ser desenvolvido e usado após o registro do cliente.
No cliente, listamos apenas duas funções relativamente importantes, e o restante é omitido.
procedimento TForm1.Button1Click (remetente: TOBJECT);
// Clique em Button1 e "diga" o conteúdo da edição
Começar
Server.speakto (edit1.text, 1);
fim;
procedimento TFFORM1.TIMER1TIMER (remetente: Tobject);
// Solicite o conteúdo da conversa do servidor de vez em quando, e eu o defino para 1,5 segundos
var
Tempstrings: tStrings;
I: Inteiro;
Começar
se server.readReady (1) = 1 então
Começar
Tempstrings: = tStringList.create;
Setolestrings (tempstrings, server.readFrom (1));
Se Freadstartpos> 19 então
if (fclearBufferTag = 0-server.testclearBufferTag (1)) então
Começar
FreadstartPos: = 0;
FclearBufferTag: = server.testclearBufferTag (1);
fim;
para i: = freadstartpos para tempstrings.count-1 do
Memando1.lines.add (tempstrings [i]);
FreadstartPos: = tempstrings.count;
fim;
fim;
A parte principal de uma sala de bate-papo LAN baseada em DCOM foi basicamente concluída e todos os testes foram relativamente suaves. Também é feito.