国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

開發(fā)一個(gè)基于DCOM的局域網(wǎng)聊天室(三)

2019-11-18 18:25:16
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
 

(接上文)

完善和修補(bǔ):

基于修正通過(guò)測(cè)試所發(fā)現(xiàn)的bug,和功能的完善,我們有對(duì)客戶端進(jìn)行了一定的改動(dòng),主要體現(xiàn)在:

·對(duì)客戶端進(jìn)行更好的異常處理,以防止由于服務(wù)器異常中斷而導(dǎo)致客戶端仍不端請(qǐng)求服務(wù)器所造成的死鎖。

·增加了說(shuō)話對(duì)象和悄悄話功能(在客戶端實(shí)現(xiàn))

·增加了登錄窗體,可以登陸到指定的房間并對(duì)服務(wù)器進(jìn)行配置(參看下面服務(wù)器的改進(jìn))

另外在服務(wù)器端我們也做了部分的改進(jìn),主要完成了上次沒有實(shí)現(xiàn)的功能,主要體現(xiàn)在:

·完成了服務(wù)器端任意配置并開放多個(gè)話題房間的功能(一個(gè)TchatRoom的實(shí)例對(duì)應(yīng)著一個(gè)話題房間)

·在服務(wù)器端的每個(gè)房間維護(hù)一份登錄進(jìn)房間的人員列表,供客戶端調(diào)用

·完善了服務(wù)器端的UI,并在服務(wù)器端實(shí)現(xiàn)為每個(gè)用戶的登錄和登出進(jìn)行向客戶系統(tǒng)公告的功能,并在服務(wù)器端限制登錄的人數(shù)和進(jìn)行重名判斷

我們來(lái)看看主要的改進(jìn)部分的代碼變化情況,首先是服務(wù)器端的接口:

 

  IChatManager = interface(IDispatch)

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

    ……

    function GetRoomList: IStrings; safecall;//客戶端獲得服務(wù)器端的房間列表

    function RoomCanLogin(RoomID: Integer; const UserName: WideString): Integer; safecall;

    //客戶端接收到一個(gè)返回值用以判斷服務(wù)器是否允許客戶登錄

    //返回值的表示:1:可以登陸 2:用戶重名 3:人數(shù)過(guò)多

    function RoomUserList(RoomID: Integer): IStrings; safecall;

    //供客戶端獲得在一個(gè)房間內(nèi)的人員列表,由TchatRoom維護(hù)這個(gè)列表

    //每登錄和離開一個(gè)user便更新列表

  end;

 

其中RoomCanLogin需要的實(shí)現(xiàn)比較重要,其余的兩個(gè)接口只是返回有服務(wù)器維護(hù)的兩個(gè)列表而已。

 

//RoomCanLogin方法對(duì)應(yīng)于TchatRoom類內(nèi)的實(shí)現(xiàn)

function TChatRoom.CanLogin(UserName:string): integer;

var

 i:integer;

begin

 result:=1;

 if FRoomUserList.Count>50 then //最多允許一個(gè)房間有50個(gè)人

 begin

  result:=3;

  exit;

 end;

 for i:=0 to FRoomUserList.Count-1 do

 //遍歷由TchatRoom維護(hù)的人員列表以判斷是否有重名用戶

 begin

  if FRoomUserList[i]=UserName then

   result:=2;

  break;

 end;

end;

 

再來(lái)看看,上次沒有實(shí)現(xiàn)的多話題房間維護(hù):

 

//請(qǐng)對(duì)比上篇文章的同名實(shí)現(xiàn)

constructor TChatRoomManager.Create;

var

 i:integer;

begin

 FRoomList:=TStringList.Create;

 try

  FRoomList.LoadFromFile(ExtractFilePath(application.ExeName)+'ChatRoomList.ini');

 except

  on E:Exception do

  begin

   application.MessageBox(Pchar('配置文件錯(cuò)誤,錯(cuò)誤代碼:'+E.Message),'DComChat

   application.Terminate;

  end;

 end;

 FRoomList.Delete(0);

 FRoomCount:=FRoomList.Count;

 //這里將從配置文件中讀出有幾個(gè)聊天室

 setlength(ChatRoom,FRoomCount);

 for i:=1 to FRoomCount do

  ChatRoom[i]:=TChatRoom.Create(FRoomList[i-1],i);

  //創(chuàng)建房間的每一個(gè)實(shí)例

end;

 

客戶端的Timer.OnTimer的重要改進(jìn)(悄悄話和說(shuō)話對(duì)象的功能都在這里實(shí)現(xiàn)):

 

//請(qǐng)對(duì)比上篇文章的同名實(shí)現(xiàn)

procedure TClientMainForm.Timer1Timer(Sender: TObject);

var

 TempStrings:TStrings;

 i:integer;

 ToStartPos,ToEndPos:integer;

 FromWho,ToWho,TempName:string;

begin

 try

  if ChatServer.Server.ReadReady(RoomID)=1 then

  begin

   TempStrings:=TStringList.Create;

   SetOleStrings(TempStrings,ChatServer.Server.ReadFrom(RoomID));

   if FReadStartPos>19 then

    if (FClearBufferTag=0-ChatServer.Server.TestClearBufferTag(RoomID)) then

    begin

     FReadStartPos:=0;

     FClearBufferTag:=ChatServer.Server.TestClearBufferTag(RoomID);

    end;

   for i:=FReadStartPos to TempStrings.Count-1 do

   begin

    if RightStr(TempStrings[i],11)='SecretSpeak' then

    //可以看到實(shí)現(xiàn)悄悄話無(wú)非是在說(shuō)話內(nèi)容的最后加了一個(gè)特殊的標(biāo)示SecretSpeak

    begin

     //這一段程序從字符串中解析出說(shuō)話的對(duì)象

     ToStartPos:=pos(' 悄悄的對(duì) ',TempStrings[i]);

     FromWho:=Copy(TempStrings[i],1,ToStartPos-1);//誰(shuí)說(shuō)的

     ToStartPos:=ToStartPos+10;

     ToEndPos:=pos(' 說(shuō):',TempStrings[i]);

     ToWho:=Copy(TempStrings[i],ToStartPos,ToEndPos-ToStartPos);//說(shuō)給誰(shuí)

     ////////////////////////////////////////////////////////////////////////////////////////////////////

     if (ToWho='所有人') or (ToWho=UserName) or (FromWho=UserName) then

     //是自己說(shuō)的,或自己應(yīng)該看到的,或是說(shuō)給所有人的悄悄話都有權(quán)看到

     begin

      Memo1.Lines.Add(Copy(TempStrings[i],1,length(TempStrings[i])-11));

      Memo1.Lines.Add('');

     end;

    end

    else //不該看到的內(nèi)容

    begin

     Memo1.Lines.Add(TempStrings[i]);

     Memo1.Lines.Add('');

    end;

   end;

   FReadStartPos:=TempStrings.Count;

  end;

  //刷新在線人員列表

  Listbox1.Clear;

  SetOleStrings(ListBox1.Items,ChatServer.Server.RoomUserList(RoomID));

  //刷新說(shuō)話對(duì)象列表

  TempName:=SpeakToCBx.Text;

  SpeakToCBx.Clear;

  SpeakToCBx.Items.Assign(ListBox1.Items);

  SpeakToCBx.Items.Insert(0,'所有人');

  for i:=0 to SpeakToCBx.Items.Count-1 do

  begin

   if SpeakToCBx.Items[i]=TempName then Break;

  end;

  if i>SpeakToCBx.Items.Count-1 then i:=0;

  SpeakToCBx.ItemIndex:=i;

  //////////////////////////////////////////////////////////////////

 except //異常處理

  on E:Exception do

  begin

   Timer1.Enabled:=false;

   application.MessageBox

    (pchar('通信中斷或服務(wù)器故障,點(diǎn)確定后將關(guān)閉程序,請(qǐng)稍后重啟動(dòng)。詳細(xì)中斷原因:'+E.Message),'DCOMChatClient',MB_ICONWARNING);

   application.Terminate;

  end;

 end;

end;

 

當(dāng)然上面的程序所分析的字符串(說(shuō)給誰(shuí),誰(shuí)說(shuō)的,是否是悄悄話)都是在speak時(shí)產(chǎn)生的,這相當(dāng)?shù)暮?jiǎn)單:

 

//客戶端的speak

procedure TClientMainForm.Button1Click(Sender: TObject);

var

 content:string;

begin

 if Edit1.Text='' then

 begin

  application.MessageBox('不能發(fā)空消息。','DCOMChatClient',MB_ICONINFORMATION);

  exit;

 end;

 if length(edit1.Text)>100 then

 begin

  application.MessageBox('說(shuō)話內(nèi)容過(guò)長(zhǎng)。','DCOMChatClient',MB_ICONINFORMATION);

  exit;

 end;

 if CheckBox1.Checked then

  Content:=UserName+' 悄悄的對(duì) '+SpeakToCBx.Text+' 說(shuō):'+edit1.Text+'SecretSpeak'

  //可以看到悄悄話功能和說(shuō)話對(duì)象的功能只是在字符串上的簡(jiǎn)單處理罷了

 else

  Content:=UserName+' 對(duì) '+SpeakToCBx.Text+' 說(shuō):'+edit1.Text;

 ChatServer.Server.SpeakTo(Content,RoomID);

 edit1.Clear;

end;

 

至此這個(gè)程序已經(jīng)基本完善了,我們可以打包發(fā)布它,以免去最終用戶配置DCOM的麻煩。

                                                             (全文完)


上一篇:發(fā)送電子郵件

下一篇:動(dòng)態(tài)設(shè)置系統(tǒng)日期格式

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
學(xué)習(xí)交流
熱門圖片

新聞熱點(diǎn)

疑難解答

圖片精選

網(wǎng)友關(guān)注

主站蜘蛛池模板: 高台县| 东源县| 凌云县| 黄大仙区| 乃东县| 旺苍县| 交口县| 太和县| 肥乡县| 且末县| 贵定县| 巴里| 舒兰市| 怀安县| 襄城县| 康乐县| 无为县| 富裕县| 稷山县| 青阳县| 仙游县| 新竹县| 蚌埠市| 抚顺县| 新化县| 高台县| 南宫市| 武邑县| 宜昌市| 宣汉县| 甘孜县| 滕州市| 宜君县| 合肥市| 定日县| 景洪市| 宜川县| 德昌县| 托克逊县| 陵川县| 阿鲁科尔沁旗|