L'émergence de COM distribuée (ci-après dénommée DCOM) nous offre la possibilité de créer facilement des applications distribuées; applications, les développeurs peuvent presque ignorer MS-RPC) et développer des fonctions puissantes et un faible couplage (les modules fonctionnels sont relativement indépendants, Il a fait bon usage des idées d'OO) et est facile à déployer le système informatique distribué.
Dans cet article, nous avons l'intention d'utiliser DCOM pour développer une salle de chat LAN, non seulement en tant que recherche technique, mais en fait, je crois que cela devrait également être un outil utile. Tout d'abord, nous devons avoir une compréhension générale des fonctions de cette salle de chat:
1. Au moins, cette salle de chat devrait permettre à plusieurs utilisateurs LAN de discuter.
2. Il devrait y avoir des salles de sous-chat avec plusieurs sujets, et les utilisateurs peuvent choisir d'entrer dans une salle de chat pour discuter.
3. Le client doit être aussi simple que possible (sans configurer DCOM), et un côté serveur doit gérer tous les comportements d'interaction, gérer le nombre de salles de chat et de configurations connexes et faire du bon travail dans la surveillance et la journalisation du système.
4. Développez les fonctions de salle de discussion (telles que les fonctions de conversation silencieuses, les emojis, etc.). Sur la base de la description fonctionnelle ci-dessus, après avoir soigneusement analysé le problème, nous avons conçu le croquis suivant:
Dans cet article, nous souhaitons mettre en œuvre à peu près un noyau de base de ce programme, notamment IchatManager, Tchatroomager et Tchatroom, pour remplir le serveur avec les fonctions les plus basiques et pour effectuer une simple détection du client. Nous nous concentrons sur le côté serveur, car il implémentera la plupart des fonctions de la salle de chat, et le client n'est qu'un programme très petit et simple.
En raison de l'espace, nous énumérons uniquement le code pour les pièces importantes. Tout d'abord, jetons un coup d'œil à quoi ressemble notre interface IchatManager:
IchatManager = Interface (iDispatch)
['{E7cd7f0d-447f-497a-8c7b-1d80e748b67f}']
Procédure Speakto (Contenu const: Waidestring; Destid: Integer);
// Le client parle de la salle désignée, et le Destid est le numéro de la salle
Fonction Readfrom (SourceId: entier): istrings;
// Le client lit le contenu de la conversation de la salle désignée, le numéro SourceId est le numéro de la salle
fonction ReadReady (id: entier): octet;
// Le client peut vérifier si la salle spécifiée peut déjà lire le contenu de la conversation
Procédure Connectroom (nom d'utilisateur CONS: Welstring; RoomID: entier);
// Les clients se connectent dans des chambres désignées
Procédure Disconnectroom (const Nom d'utilisateur: Welsestring; RoomID: entier);
// Le client sort de la salle désignée
fonction TestClearBuffertag (RoomID: entier): entier;
// teste le client si la zone tampon de la pièce spécifiée est effacée ou non
fin;
Jetons un coup d'œil à la section TchatManager de la classe d'implémentation d'interface:
taper
TchatManager = classe (tautoObject, ichatmanager)
protégé
Fonction Readfrom (SourceId: entier): istrings;
// ici, nous utilisons le type complexe tstings étendu par Delphi, afin de faire prendre en charge COM ceci
// Type, Delphi fournit l'interface Istrings
Procédure Speakto (Contenu const: Waidestring; Destid: Integer);
fonction ReadReady (id: entier): octet;
// utilisé pour fournir au client pour demander si la pièce spécifiée est lisible et si le tampon de pièce spécifié est vide
Procédure Connectroom (nom d'utilisateur CONS: Widestring; RoomID: entier);
SafeCall;
Procédure Disconnectroom (const Nom d'utilisateur: Widestring; RoomID: entier);
SafeCall;
fonction TestClearBuffertag (RoomID: entier): entier;
fin;
Partie de mise en œuvre:
var
Temproom: Tchatroom;
Commencer
Temproom: = ChatroomManager.FindroomByid (sourceId);
tandis que Temproom.
Commencer
// ne rien faire est juste en attente d'être déverrouillé
fin;
Getolestrings (temproom.oneread, résultat);
fin;
Procédure tchatManager.speakto (Contenu const: largestring; Destid: Integer);
var
Temproom: Tchatroom;
Commencer
Temproom: = ChatroomManager.FindroomByid (Destid);
tandis que Temproom.
Commencer
// ne rien faire est juste en attente d'être déverrouillé
fin;
Temproom.espeak (contenu);
fin;
fonction tchatmanager.readready (id: entier): octet;
var
Temproom: Tchatroom;
Commencer
Temproom: = ChatroomManager.FindroomById (ID);
si temproom.canread alors résultat: = 1 else Résultats: = 0;
fin;
Procédure tchatManager.Connectroom (Nom d'utilisateur Const: Welstring;
Roomide: entier);
// Le client se connecte à la salle spécifiée via l'interface et n'est pas entièrement implémentée
var
Temproom: Tchatroom;
Commencer
Temproom: = ChatroomManager.FindroomByid (RoomID);
Temproom.loginroom (nom d'utilisateur);
fin;
Procédure tchatManager.Disconnectroom (Nom d'utilisateur Const: Widestring;
Roomide: entier);
// Le client quitte la pièce spécifiée via l'interface et n'est pas entièrement implémentée
var
Temproom: Tchatroom;
Commencer
Temproom: = ChatroomManager.FindroomByid (RoomID);
Temproom.leaveroom (nom d'utilisateur);
fin;
fonction tchatManager.TestClearBuffertag (RoomID: entier): entier;
var
Temproom: Tchatroom;
Commencer
Temproom: = ChatroomManager.FindroomByid (RoomID);
Résultat: = temproom.clearbuffertag;
fin;
Initialisation
TautoObjectFactory.Create (ComServer, TchatManager, class_chatManager,
Cimultiinstance, tmapartment);
fin.
Le Tchatroom le plus important ressemble:
taper
Tchatroom = classe
Privé
Fbuffer: array [1..20] de String;
FbufferLength: entier;
Foomname: String;
Fomide: entier;
Floqué: Boolean; // Lock synchrone, utilisé pour gérer la situation où plusieurs personnes envoient des conversations en même temps
FconnectCount: entier; // le nombre actuel de personnes dans la salle
Fclearbuffertag: entier;
// Cette valeur sautera une fois à chaque fois que le tampon est effacé, et cette impulsion est détectée par le client
protégé
procédure clearbuffer; // effacer le tampon
fonction getCanRead: boolean;
publique
Constructeur Create (RoomName: String; RoomID: INTEGER);
Procédure OneSpeak (Contenu: String); // Ajouter un contenu de chat au tampon
Procédure Loginroom (nom d'utilisateur: chaîne); // se référer à la partie d'implémentation des commentaires
Procédure Leveroom (nom d'utilisateur: chaîne); // se référer à la partie d'implémentation des commentaires
fonction OneRead: tStrings; // Lisez l'enregistrement dans le tampon
Propriété verrouillée: Boolean Read Floked;
Property Canread: Boolean Read GetCanRead; // Déterminez si le tampon est vide, sinon il est illisible
Propriété ClearBuffertag: Integer Read FclearBuffertag;
fin;
Implémentation de Tchatroom:
{Tchatroom}
Constructeur Tchatroom.Create (RoomName: String; RoomID: entier);
Commencer
FbufferLength: = 0;
FconnectCount: = 0;
Fclearbuffertag: = 1;
Afflué: = false;
Foomname: = RoomName;
Fomide: = Roomide;
fin;
procédure tchatroom.clearbuffer;
var
I: entier;
Commencer
/// Ici, vous pouvez détecter un indicateur pour déterminer si le serveur doit enregistrer chaque contenu de chat.
pour i: = 1 à 20 do
Fbuffer [i]: = '';
FbufferLength: = 0;
Fclearbuffertag: = 0-fclearbuffertag;
fin;
procédure tchatroom.espeak (contenu: chaîne);
Commencer
Afflué: = true;
Inc (fbufferLength);
Si fbufferLength> 20 alors
Commencer
Clearbuffer;
Inc (fbufferLength);
fin;
FBuffer [fbufferLength]: = contenu;
Afflué: = false;
fin;
fonction tchatroom.oneread: tStrings;
var
Fstrings: tStrings;
I: entier;
Commencer
Afflué: = true;
Fstrings: = tStringList.Create;
pour i: = 1 à fbufferLength
Fstrings.add (fbuffer [i]);
Résultat: = fstrings;
Afflué: = false;
fin;
fonction tchatroom.getCanread: booléen;
Commencer
Résultat: = false;
Si fbufferLength> 0 alors résultat: = true;
fin;
Procédure tchatroom.loginroom (nom d'utilisateur: chaîne);
// L'événement de salle de chat de connexion utilisateur n'est pas entièrement implémenté ici
Commencer
Inc (fconnectCount);
fin;
Procédure tchatroom.leaveroom (nom d'utilisateur: chaîne);
// l'utilisateur quitte l'événement de salle de chat, il n'est pas entièrement implémenté ici
Commencer
Dec (fconnectCount);
fin;
La dernière partie importante du côté serveur TchatroomManager:
taper
TchatroomManager = classe
Privé
Chatroom: Tableau de Tchatroom;
publique
constructeur créé;
Fonction FindroomByid (ID: entier): Tchatroom;
fin;
Partie de mise en œuvre:
{TchatroomManager}
Constructeur TchatroomManager.Create;
var
I, RoomCount: entier;
RoomNames: tStrings; // RoomName est le nom de la salle de chat dans le fichier de configuration
Commencer
RoomCount: = 1;
// Ici, nous lirons plusieurs salles de chat dans le fichier de configuration.
RoomNames: = tStringList.Create;
RoomNames.Add ('Testroom'); // Cette phrase sera remplacée par la lecture finale du fichier de configuration.
SetLength (Chatroom, RoomCount);
pour i: = 1 à roomcount do
Chatroom [i]: = tchatroom.create (RoomNames [i-1], i);
fin;
fonction tchatroomManager.Findroombyid (ID: entier): Tchatroom;
// Cette fonction est appelée par l'interface IchatManager, car la version finale de l'interface sera fournie au client
// La fonction d'obtenir la liste des chambres est pour que le client connaisse l'identification de sa chambre
Commencer
Résultat: = Chatroom [ID];
fin;
Initialisation
ChatroomManager: = TchatroomManager.Create;
fin.
Une fois la partie principale principale du côté serveur terminé, nous configurons la configuration DCOM côté serveur et pouvons développer un client simple pour les tests: (bien que le client soit aussi simple que possible, nous n'avons pas besoin de configurer DCOM, mais nous Besoin de copier le type de serveur.
Sur le client, nous énumérons seulement deux fonctions relativement importantes, et les autres sont omis.
Procédure tform1.button1Click (expéditeur: tobject);
// Cliquez sur Button1 et "Say" le contenu de l'édition
Commencer
Server.speakto (edit1.text, 1);
fin;
Procédure TForm1.Timer1Timer (expéditeur: TOBject);
// demande le contenu de conversation du serveur de temps en temps, et je l'ai réglé à 1,5 seconde
var
TEMPSTRINGS: TSTRINGS;
I: entier;
Commencer
si server.readready (1) = 1 alors
Commencer
Tempstrings: = TStringList.Create;
SetOlestrings (tempstrings, server.readfrom (1));
Si Freadstartpos> 19 alors
if (fclearbuffertag = 0-server.testClearbuffertag (1)) puis
Commencer
FreadStartpos: = 0;
Fclearbuffertag: = server.testClearBuffertag (1);
fin;
pour i: = freadstartpos à tempsstrings.count-1 do
Memo1.lines.add (tempsstrings [i]);
FreadStartpos: = TEMPSTRINGS.COUNT;
fin;
fin;
La partie principale d'une salle de chat LAN basée sur DCOM a été essentiellement terminée, et tous les tests ont été relativement lisses. également fait.