本文我們打算使用DCOM來開發一個局域網聊天室
這篇文章中我們要大致實現這個程序的一個基本的核心
由於篇幅關系
IChatManager = interface(IDispatch)
[
procedure SpeakTo(const content: WideString; destid: Integer); safecall;
//客戶向指定的房間說話
function ReadFrom(sourceid: Integer): IStrings; safecall;
//客戶從指定的房間讀取談話內容
function ReadReady(id: Integer): Byte; safecall;
//客戶檢測指定的房間是否已經可以讀取談話內容
procedure ConnectRoom(const UserName: WideString; RoomID: Integer); safecall;
//客戶登陸指定房間
procedure DisconnectRoom(const UserName: WideString; RoomID: Integer); safecall;
//客戶退出指定房間
function TestClearBufferTag(RoomID: Integer): Integer; safecall;
//客戶測試指定房間的緩沖區的清空與否狀況
end;
再來看看接口的實現類TChatManager部分
type
TChatManager = class(TAutoObject
protected
function ReadFrom(sourceid: Integer): IStrings; safecall;
//在這裡我們使用Delphi擴展的復雜類型TStings
//類型
procedure SpeakTo(const content: WideString; destid: Integer); safecall;
function ReadReady(id: Integer): Byte; safecall;
//用來提供給客戶端查詢指定的房間是否可讀
procedure ConnectRoom(const UserName: WideString; RoomID: Integer);
safecall;
procedure DisconnectRoom(const UserName: WideString; RoomID: Integer);
safecall;
function TestClearBufferTag(RoomID: Integer): Integer; safecall;
end;
實現部分
function TChatManager
var
TempRoom:TChatRoom;
begin
TempRoom:=ChatRoomManager
while TempRoom
begin
//do nothing只是等待解鎖
end;
GetOleStrings(TempRoom
end;
procedure TChatManager
var
TempRoom:TChatRoom;
begin
TempRoom:=ChatRoomManager
while TempRoom
begin
//do nothing只是等待解鎖
end;
TempRoom
end;
function TChatManager
var
TempRoom:TChatRoom;
begin
TempRoom:=ChatRoomManager
if TempRoom
end;
procedure TChatManager
RoomID: Integer);
//客戶端通過接口登陸到指定的房間
var
TempRoom:TChatRoom;
begin
TempRoom:=ChatRoomManager
TempRoom
end;
procedure TChatManager
RoomID: Integer);
//客戶端通過接口離開指定的房間
var
TempRoom:TChatRoom;
begin
TempRoom:=ChatRoomManager
TempRoom
end;
function TChatManager
var
TempRoom:TChatRoom;
begin
TempRoom:=ChatRoomManager
result:=TempRoom
end;
initialization
TAutoObjectFactory
ciMultiInstance
end
比較關鍵TchatRoom是下面的樣子
type
TChatRoom=class
private
FBuffer:array[
FBufferLength:integer;
FRoomName:string;
FRoomID:integer;
FLocked:boolean;//同步鎖
FConnectCount:integer;//當前房間的人數
FClearBufferTag:integer;
//每清空一次buffer此值便跳變一次
protected
procedure ClearBuffer;//清空緩沖區
function GetCanRead:boolean;
public
constructor Create(RoomName:string;RoomID:integer);
procedure OneSpeak(content:string);//將一條聊天內容加入緩沖區
procedure LoginRoom(UserName:string);//參看實現部分注釋
procedure LeaveRoom(UserName:string);//參看實現部分注釋
function OneRead:Tstrings;//從緩沖區中讀出記錄
property Locked:boolean read FLocked; //readonly;//供IChatManager檢測
property CanRead:boolean read GetCanRead;//判斷緩沖區是否為空
property ClearBufferTag:integer read FClearBufferTag;
end;
TchatRoom的實現
{ TChatRoom }
constructor TChatRoom
begin
FBufferLength:=
FConnectCount:=
FClearBufferTag:=
FLocked:=false;
FRoomName:=RoomName;
FRoomID:=RoomID;
end;
procedure TChatRoom
var
i:integer;
begin
///在這裡可以檢測一個標志
for i:=
FBuffer[i]:=
FBufferLength:=
FClearBufferTag:=
end;
procedure TChatRoom
begin
FLocked:=true;
inc(FBufferLength);
if FBufferLength>
begin
ClearBuffer;
inc(FBufferLength);
end;
FBuffer[FBufferLength]:=content;
FLocked:=false;
end;
function TChatRoom
var
FStrings:TStrings;
i:integer;
begin
FLocked:=true;
FStrings:=TStringList
for i:=
FStrings
result:=FStrings;
FLocked:=false;
end;
function TChatRoom
begin
result:=false;
if FBufferLength>
end;
procedure TChatRoom
//用戶登陸聊天室事件
begin
inc(FConnectCount);
end;
procedure TChatRoom
//用戶離開聊天室事件
begin
Dec(FConnectCount);
end;
服務器端的最後一個比較重要的部分TchatRoomManager
type
TChatRoomManager=class
private
ChatRoom:array of TChatRoom;
public
constructor Create;
function FindRoomByID(id:integer):TChatRoom;
end;
實現部分
{ TChatRoomManager }
constructor TChatRoomManager
var
i
RoomNames:TStrings;//RoomName是配置文件中的聊天室名稱
begin
RoomCount:=
//這裡將從配置文件中讀出有幾個聊天室
RoomNames:=TStringList
RoomNames
setlength(ChatRoom
for i:=
ChatRoom[i]:=TChatRoom
end;
function TChatRoomManager
//該函數由IChatManager接口調用
//端得到房間列表的功能
begin
result:=ChatRoom[id];
end;
initialization
ChatRoomManager:=TChatRoomManager
end
在服務器端的主要核心部分完成以後
在客戶端我們只列出兩個相對重要的函數
procedure TForm
//點擊button
begin
Server
end;
procedure TForm
//每隔一段時間向服務器請求談話內容
var
TempStrings:TStrings;
i:integer;
begin
if Server
begin
TempStrings:=TStringList
SetOleStrings(TempStrings
if FReadStartPos>
if (FClearBufferTag=
begin
FReadStartPos:=
FClearBufferTag:=Server
end;
for i:=FReadStartPos to TempStrings
Memo
FReadStartPos:=TempStrings
end;
end;
一個基於DCOM的局域網聊天室的核心部分就基本完成了
From:http://tw.wingwit.com/Article/program/Delphi/201311/24839.html