Develop a DCOM-based local area online chat room
Difficulty: ★★★ ☆☆
First knowledge: Delphi / interface / OLE & COM & DCOM / WIN32
First of all, I wish you all a happy New Year, the monkey year!
In the previous series, we have discussed many related technologies based on Microsoft COM, while the emergence of distributed COM (DCOM) provides us with easy creation of distributed applications; we can do not pay low Level Windows Sockets (DCOM communicates with the object through MS-RPC, lucky to develop COM applications, developers can almost do not pay attention to MS-RPC) and develop powerful, low coupares (function modules are relatively independent) , Very good ideas for OO), easy to deploy distributed computing systems.
In this article, we plan to use DCOM to develop a local area online chat room, not only as a technical research, but in fact, I believe that this should be a useful tool. First we have to have a roughly understanding of this chat room: 1. At least this chat room should allow multiple local area network users to chat. (A little nonsense ...) 2, you should be able to have multiple topics, users can choose to enter a chat room. 3, the client should try as simple as possible (no configured DCOM), and require a server to manage all interactive behavior, managing the number of chat rooms and related configurations, and do system monitoring and logging. 4. Expand the chat room function (such as a private message, emoch symbol, etc.). According to the above functions, we designed the sketch below after careful analysis of the problem:
In this article, we must roughly implement a basic core of this program, including iChatManager, TchanManager, Tchatroom, complete a one of the most basic functions, and make a simple client for detection. Our focus is the server side, because it will implement most of the functions of the chat room, the client is just a very small and simple program.
Due to the space relationship, we only list the important part of the code, please send me email for a complete program. Let's take a look at what our ICHATMANAGER interface is like (because we only achieve the most basic function, this interface is not complete, we will give a complete statement in future articles):
IChatManager = Interface (Idispatch)
['{E7CD7F0D-447F-497A-8C7B-1D80E748B67F}']]
Procedure Speakto (Const Content: WideString; Destid: Integer); SaFECALL;
/ / The customer speaks to the designated room, Destid is the room number
Function ReadFrom (SourceId: Integer): istrings; SaFECALL;
// Customer reads the conversation content from the specified room, SourceId is the room number
Function ReadReady (ID: Integer): byte; SaFECALL;
/ / Customer Detection The specified room can be read on the conversation content
Procedure Connectroom (const username: wideString; roomid: integer); SaFECALL;
/ / Customer login to the specified room
Procedure disconnectroom (const username: wideString; roomid: integer); SaFECALL;
// Customer exits the specified room
Function TestClearBuffertag (Roomid: Integer): Integer; SaFECALL; / / Customer Test the empty or notice of the buffer of the specified room
END;
Let's take a look at the implementation of the interface TCHATMANAGER section:
Type
TchatManager = Class (Tautoobject, iChatManager)
protected
Function ReadFrom (SourceId: Integer): istrings; SaFECALL;
/ / Here we use Delphi extension complex type TSTINGS, in order to support this
// Type, Delphi provides an istrings interface
Procedure Speakto (Const Content: WideString; Destid: Integer); SaFECALL;
Function ReadReady (ID: Integer): byte; SaFECALL;
// Used to provide whether the specified room is readily read, specify whether the room buffer is empty
Procedure Connectroom (const username: wideString; roomid: integer);
SafeCall;
Procedure disconnectroom (const username: wideString; roomid: integer);
SafeCall;
Function TestClearbuffertag (Roomid: Integer): Integer; SaFECALL;
END;
Implementation part:
Function Tchatmanager.readFrom (SourceId: Integer): Istrings;
VAR
Temproom: tchatroom;
Begin
Temproom: = chatroommanager.findroombyid (SourceID);
While TemProom.locked Do
Begin
// do nothing just waiting to unlock
END;
Getolestrings (TemProom.onRead, Result);
END;
Procedure tchatmanager.speakto (const content: wideString; destID: integer);
VAR
Temproom: tchatroom;
Begin
TemProom: = chatroommanager.findroombyid (destID);
While TemProom.locked Do
Begin
// do nothing just waiting to unlock
END;
TemProom.onespeak (Content);
END;
Function tchatmanager.readready (ID: integer): byte;
VAR
Temproom: tchatroom;
Begin
TemProom: = chatroommanager.findroombyid (ID);
If TemProom.canRead Then Result: = 1 else result: = 0;
END;
Procedure tchatmanager.connectroom (const username: wideString)
Roomid: integer;
/ / The client logs in to the specified room through the interface, not fully realized
VAR
Temproom: tchatroom;
Begin
TemProom: = chatroommanager.findroombyid (roomid);
TemProom.loginroom (UserName);
END;
Procedure tchatmanager.disconnectroom (const username: wideString; roomid: integer);
/ / The client leaves the specified room through the interface, not fully realized
VAR
Temproom: tchatroom;
Begin
TemProom: = chatroommanager.findroombyid (roomid);
TemProom.Leaveroom (username);
END;
Function Tchanager.TestClearBuffertag (Roomid: Integer): Integer;
VAR
Temproom: tchatroom;
Begin
TemProom: = chatroommanager.findroombyid (roomid);
Result: = TemProom.clearBuffertag;
END;
INITIALIZATION
TautoobjectFactory.create (Comserver, Tchatmanager, Class_Chatmanager,
CIMULTIINSTANCE, TMAPARTMENT);
End.
Compare the key Tchanom is below:
Type
Tchatroom = Class
Private
FBuffer: array [1..20] of string;
FBufferLength: Integer;
Froomname: String;
Froomid: integer;
FLOCKED: BOOLEAN; / / Synchronous lock, the situation used to handle multiplayer simultaneously
FconnectCount: Integer; // The number of people currently
FCLEARBUFFERTAG: Integer;
/ / Each time the buffer is jumped once, this pulse is detected by the client.
protected
Procedure ClearBuffer; / / Clear Buffer
Function getcanread: bolean;
public
Constructor Create (roomname: string; roomid: integer);
Procedure OneSpeak (Content: String); // Add a chat content to the buffer
Procedure loginroom (username: string); // See the implementation part of the comment
Procedure LeaveRoom (username: string); // See the implementation part of the comment
Function OneRead: Tstrings; // Read records from buffers
Property Locked: Boolean Read flocked; // readonly; // For iChatManager detection
Property canread: boolean read getcanread; // Determine if the buffer is empty, otherwise it is not readable.
Property ClearBuffertag: Integer Read FclearBuffertag;
END; (backwent)