delphi聊天室:Delphi开发基于DCOM的聊天室

  分布式COM(以下简称DCOM)出现给我们轻松创建分布式应用提供了机会;我们可以完全不去理会低级别Windows Sockets(DCOM通过MS-RPC让客户和对象进行通信幸运是要开发COM应用开发者几乎可以不去理会MS-RPC)而开发出功能强大、偶合性低(功能模块相对独立很好发挥了OO思想)、易于部署分布式计算系统

  本文我们打算使用DCOM来开发个局域网聊天室不仅是作为技术上研究实际上我相信这应该也是个有用工具首先我们要对这个聊天室功能有个大致了解:

  1、至少这个聊天室应该允许多个局域网用户进行聊天
  
  2、应该能够有多个话题子聊天室用户可以选择进入某个聊天室进行聊天

  3、客户端应该尽量简单(不用配置DCOM)并需要个服务器端管理所有交互行为管理聊天室数目和相关配置并做好系统监测和日志记录等

  4、对聊天室功能进行扩展(如悄悄话功能表情符号等)根据以上功能描述在仔细分析问题以后我们设计出下面草图:



  这篇文章中我们要大致实现这个个基本核心包括IChatManager、TChatRoomManager、TchatRoom完成个最基本功能服务器端并做个简单客户端进行检测我们重点是服务器端它将实现聊天室大部分功能客户端只是个十分小巧简单

  由于篇幅关系我们只列出重要部分代码完整请给我发email首先来看看我们IchatManager接口是什么样子:

IChatManager = erface(IDispatch)

['{E7CD7F0D-447F-497A-8C7B-1D80E748B67F}']

procedure SpeakTo(const content: WideString; destid: Integer); safecall;

//客户向指定房间说话destid为房间号

function ReadFrom(sourceid: Integer): IStrings; safecall;

//客户从指定房间读取谈话内容sourceid为房间号

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 = (TAutoObject, IChatManager)

protected

function ReadFrom(sourceid: Integer): IStrings; safecall;

//在这里我们使用Delphi扩展复杂类型TStings为了让COM支持这种

//类型delphi提供了IStrings接口

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.ReadFrom(sourceid: Integer): IStrings;

var

TempRoom:TChatRoom;

begin

TempRoom:=ChatRoomManager.FindRoomByID(sourceid);

while TempRoom.Locked do

begin

//do nothing只是等待解锁

end;

GetOleStrings(TempRoom.OneRead,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只是等待解锁

end;

TempRoom.OneSpeak(content);

end;

function TChatManager.ReadReady(id: Integer): Byte;

var

TempRoom:TChatRoom;

begin

TempRoom:=ChatRoomManager.FindRoomByID(id);

TempRoom.CanRead then result:=1 Result:=0;

end;

procedure TChatManager.ConnectRoom(const UserName: WideString;

RoomID: Integer);

//客户端通过接口登陆到指定房间没有完全实现

var

TempRoom:TChatRoom;

begin

TempRoom:=ChatRoomManager.FindRoomByID(RoomID);

TempRoom.LoginRoom(UserName);

end;

procedure TChatManager.DisconnectRoom(const UserName: WideString;

RoomID: Integer);

//客户端通过接口离开指定房间没有完全实现

var

TempRoom:TChatRoom;

begin

TempRoom:=ChatRoomManager.FindRoomByID(RoomID);

TempRoom.LeaveRoom(UserName);

end;

function TChatManager.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.


  比较关键TchatRoom是下面样子:

type

TChatRoom=

private

FBuffer:.gif' />[1..20] of ;

FBufferLength:eger;

FRoomName:;

FRoomID:eger;

FLocked:boolean;//同步锁用来处理多人同时发出对话情况

FConnectCount:eger;//当前房间人数

FClearBufferTag:eger;

//每清空次buffer此值便跳变此脉冲被客户端检测

protected

procedure ClearBuffer;//清空缓冲区

function GetCanRead:boolean;

public

constructor Create(RoomName:;RoomID:eger);

procedure _disibledevent=TempStrings.Count;

end;

end;


  个基于DCOM局域网聊天室核心部分就基本完成了并且所有测试都比较顺利这里需要补充介绍说明下聊天室服务器个难点:就是需要开发者非常谨慎处理同步虽然我也进行了同步处理但在客户端人数众多情况下仍然可能发生死锁或其它活锁情况这个还需要更进测试、甚至进行重构
Tags:  delphi数据库开发 delphi开发实例 delphi开发 delphi聊天室

延伸阅读

最新评论

发表评论