분산 COM (이하 DCOM이라고 함)의 출현은 분산 응용 프로그램을 쉽게 만들 수있는 기회를 제공합니다. DCOM은 MS-RPC를 통해 객체와 통신 할 수 있습니다. 응용 프로그램, 개발자는 MS-RPC를 거의 무시하고 강력한 기능과 낮은 커플 링을 개발할 수 있습니다 (기능 모듈은 비교적 독립적입니다. OO의 아이디어를 잘 활용했으며 분산 컴퓨팅 시스템을 쉽게 배포 할 수 있습니다.
이 기사에서는 DCOM을 사용하여 기술 연구뿐만 아니라 LAN 채팅방을 개발하려고 할뿐만 아니라 실제로 이것이 유용한 도구라고 생각합니다. 우선, 우리는이 대화방의 기능에 대한 일반적인 이해가 필요합니다.
1. 적어도이 채팅방은 여러 LAN 사용자가 채팅 할 수 있어야합니다.
2. 여러 주제가있는 하위 샤트 룸이 있어야하며 사용자는 채팅방에 들어가서 채팅을 선택할 수 있습니다.
3. 클라이언트는 가능한 한 간단해야하며 (DCOM을 구성하지 않고) 서버 측은 모든 상호 작용 동작을 관리하고, 채팅방 수 및 관련 구성을 관리하고, 시스템 모니터링 및 로깅에 적합한 작업을 수행해야합니다.
4. 채팅방 기능 (예 : 조용한 대화 기능, 이모티콘 등)을 확장하십시오. 위의 기능 설명을 바탕으로 문제를 신중하게 분석 한 후 다음 스케치를 설계했습니다.
이 기사에서는 Ichatmanager, Tchatroommanager 및 TChatroom을 포함한이 프로그램의 기본 핵심을 대략 구현하여 가장 기본적인 기능을 갖춘 서버를 완성하고 간단한 클라이언트 탐지를 수행하려고합니다. 우리의 초점은 서버 측에 중점을두고 있습니다. 채팅방의 대부분의 기능을 구현하고 클라이언트는 매우 작고 간단한 프로그램입니다.
공간으로 인해 중요한 부분에 대한 코드 만 나와 있습니다. 먼저 Ichatmanager 인터페이스의 모습을 살펴 보겠습니다.
ichatmanager = 인터페이스 (idispatch)
[ '{e7cd7f0d-447f-497a-8c7b-1d80e748b67f}']
절차 speakto (const 컨텐츠 : widestring; destid : 정수);
// 클라이언트는 지정된 방과 대화하고 대상은 객실 번호입니다.
함수 readfrom (SourceId : Integer) : istrings;
// 클라이언트는 지정된 방에서 대화 내용을 읽고 소스는 객실 번호입니다.
기능 읽기 (ID : 정수) : 바이트;
// 고객이 지정된 방이 이미 대화 내용을 읽을 수 있는지 확인할 수 있습니다.
프로 시저 Connectroom (const username : wideString; 룸메이트 : 정수);
// 고객이 지정된 객실에 로그인합니다
프로 시저 디스크 컨트리 룸 (const username : wideString; 룸메이트 : 정수);
// 고객이 지정된 방을 나옵니다
기능 testclearbuffertag (룸메이트 : 정수) : 정수;
// 고객이 지정된 실의 버퍼 영역이 지워지는지 여부를 테스트합니다.
끝;
인터페이스 구현 클래스의 tchatmanager 섹션을 살펴 보겠습니다.
유형
tchatmanager = class (tautoobject, ichatmanager)
보호
함수 readfrom (SourceId : Integer) : istrings;
// 여기에서 우리는 com을 지원하기 위해 Delphi가 확장 한 복잡한 유형 tstings를 사용합니다.
// type, delphi는 istrings 인터페이스를 제공합니다
절차 speakto (const 컨텐츠 : widestring; destid : 정수);
기능 읽기 (ID : 정수) : 바이트;
// 지정된 객실을 읽을 수 있는지, 지정된 객실 버퍼가 비어 있는지 여부를 쿼리하기 위해 클라이언트를 제공하는 데 사용됩니다.
프로 시저 Connectroom (const username : widestring; roomid : Integer);
Safecall;
프로 시저 단절 기관 (const username : widestring; roomid : integer);
Safecall;
기능 testclearbuffertag (룸메이트 : 정수) : 정수;
끝;
구현 부분 :
var
Temproom : Tchatroom;
시작하다
Temproom : = Chatroommanager.findroombyid (SourceId);
temproom.locked
시작하다
// 아무것도 잠금 해제되기를 기다리지 않습니다
끝;
getOlestrings (Temproom.oneread, 결과);
끝;
절차 tchatmanager.speakto (const 컨텐츠 : widestring; destid : integer);
var
Temproom : Tchatroom;
시작하다
Temproom : = Chatroommanager.findroombyid (Destid);
temproom.locked
시작하다
// 아무것도 잠금 해제되기를 기다리지 않습니다
끝;
temproom.onespeak (컨텐츠);
끝;
함수 tchatmanager.readready (id : integer) : 바이트;
var
Temproom : Tchatroom;
시작하다
Temproom : = Chatroommanager.findroombyid (id);
temproom.canread 인 경우 결과 : = 1 else 결과 : = 0;
끝;
절차 tchatmanager.connectroom (const username : widestring;
룸메이트 : 정수);
// 클라이언트가 인터페이스를 통해 지정된 룸에 로그인하고 완전히 구현되지 않았습니다.
var
Temproom : Tchatroom;
시작하다
Temproom : = Chatroommanager.findroombyid (룸메이트);
temproom.loginroom (사용자 이름);
끝;
절차 tchatmanager.disconnectroom (const username : widestring;
룸메이트 : 정수);
// 클라이언트는 지정된 방을 인터페이스를 통해 방치하고 완전히 구현되지 않았습니다.
var
Temproom : Tchatroom;
시작하다
Temproom : = Chatroommanager.findroombyid (룸메이트);
Temproom.Leaveroom (사용자 이름);
끝;
함수 TCHATMANAGER.TESTCLEARBUFFERTAG (RoomId : Integer) : 정수;
var
Temproom : Tchatroom;
시작하다
Temproom : = Chatroommanager.findroombyid (룸메이트);
결과 : = temproom.clearbuffertag;
끝;
초기화
TautoObjectFactory.create (Comserver, TCHATManager, Class_chatmanager,
cimultiinstance, tmapartment);
끝.
가장 중요한 tchatroom은 다음과 같습니다.
유형
tchatroom = 클래스
사적인
fbuffer : 배열 [1..20]의 스트링;
fbufferlength : 정수;
froomname : 문자열;
Froomid : 정수;
무리 : 부울; // 동기식 잠금, 여러 사람이 동시에 대화를 보내는 상황을 처리하는 데 사용됩니다.
fconnectCount : 정수; // 방에있는 현재 사람들의 수
fclearbuffertag : 정수;
// 버퍼가 지울 때 마다이 값이 한 번 점프 하고이 펄스는 클라이언트가 감지합니다.
보호
절차 ClearBuffer; // 버퍼를 지 웁니다
기능 getCanread : 부울;
공공의
생성자 생성 (roomName : String; roomId : Integer);
절차 OneSpeak (내용 : String); // 버퍼에 채팅 내용을 추가합니다
프로 시저 로그인 룸 (사용자 이름 : 문자열); // 주석의 구현 부분을 참조하십시오
프로 시저 리버룸 (username : string); // 주석의 구현 부분을 참조하십시오
기능 oneread : tstrings; // 버퍼에서 레코드를 읽습니다
속성 잠금 : 부울 읽기 떼. // ichatmanager 감지
속성 canread : boolean read getcanread; // 버퍼가 비어 있는지 판단합니다. 그렇지 않으면 읽을 수 없습니다.
속성 Clearbuffertag : 정수 읽기 fclearbuffertag;
끝;
TCHATROOM 구현 :
{tchatroom}
생성자 TCHATROOM.CREATE (roomName : String; RoomId : Integer);
시작하다
fbufferlength : = 0;
fconnectCount : = 0;
fclearbuffertag : = 1;
무리 : = 거짓;
froomname : = roomname;
froomid : = 룸메이트;
끝;
절차 tchatroom.clearbuffer;
var
I : 정수;
시작하다
/// 여기서는 플래그를 감지하여 서버가 각 채팅 내용을 기록 해야하는지 여부를 결정할 수 있습니다.
i : = 1 ~ 20 do
fbuffer [i] : = '';
fbufferlength : = 0;
fclearbuffertag : = 0-fclearbuffertag;
끝;
절차 tchatroom.onespeak (내용 : 문자열);
시작하다
무리 : = 참;
Inc (fbufferlength);
fbufferlength> 20이면
시작하다
Clearbuffer;
Inc (fbufferlength);
끝;
fbuffer [fbufferlength] : = 내용;
무리 : = 거짓;
끝;
기능 tchatroom.
var
fstrings : tstrings;
I : 정수;
시작하다
무리 : = 참;
fstrings : = tstringlist.create;
i : = 1에서 fbufferlength do
fstrings.add (fbuffer [i]);
결과 : = fstrings;
무리 : = 거짓;
끝;
함수 tChatroom.getCanread : 부울;
시작하다
결과 : = 거짓;
fbufferlength> 0이면 결과 : = true;
끝;
절차 tchatroom.loginroom (사용자 이름 : 문자열);
// 사용자 로그인 채팅방 이벤트가 여기에서 완전히 구현되지 않았습니다.
시작하다
Inc (fconnectCount);
끝;
절차 tchatroom.Leaveroom (사용자 이름 : String);
// 사용자는 채팅방 이벤트를 떠나 여기에서 완전히 구현되지 않았습니다.
시작하다
Dec (fconnectCount);
끝;
서버 측 TCHATROOMManager의 마지막 중요한 부분 :
유형
TCHATROOMMANAGER = 클래스
사적인
채팅방 : Tchatroom의 배열;
공공의
생성자 생성;
기능 findroombyid (ID : Integer) : tchatroom;
끝;
구현 부분 :
{tchatroommanager}
생성자 TCHATROOMMANAGER.CREATE;
var
I, 룸카운트 : 정수;
roomNames : tstrings; // roomName은 구성 파일의 채팅방 이름입니다.
시작하다
룸카운트 : = 1;
// 여기서 구성 파일에서 여러 채팅방을 읽습니다.
룸 이름 : = tstringlist.create;
roomnames.add ( 'testroom'); //이 문장은 구성 파일의 최종 읽기로 대체됩니다.
setLength (채팅실, 룸카운트);
i : = 1의 경우 룸카운트
채팅방 [i] : = tchatroom.create (룸메 이름 [i-1], i);
끝;
기능 tchatroommanager.findroombyid (Id : Integer) : tchatroom;
//이 기능은 인터페이스의 최종 버전이 고객에게 제공되므로 ICHATManager 인터페이스에서 호출됩니다.
// 객실 목록을 얻는 기능은 클라이언트가 방의 ID를 알 수 있도록합니다.
시작하다
결과 : = 채팅방 [id];
끝;
초기화
chatroommanager : = tchatroommanager.create;
끝.
서버 측의 기본 코어 부분이 완료되면 서버 측 DCOM 구성을 구성하고 테스트를 위해 간단한 클라이언트를 개발할 수 있습니다. (클라이언트는 가능한 한 간단하지만 DCOM을 구성 할 필요는 없지만 여전히 우리는 여전히 서버 측 유형을 복사해야합니다. 라이브러리 파일 .tlb는 물론 클라이언트를 등록한 후에 만 개발할 수 있습니다.
클라이언트에서는 비교적 중요한 두 가지 기능 만 나열하고 나머지는 모든 프로그램을 얻기 위해 글을 쓸 것입니다.
절차 tform1.Button1click (sender : tobject);
// button1을 클릭하고 "say"편집 내용
시작하다
server.speakto (edit1.text, 1);
끝;
절차 tform1.Timer1Timer (Sender : Tobject);
// 한 번에 한 번 서버에서 대화 내용을 요청하고 1.5 초로 설정했습니다.
var
온도 : tstrings;
I : 정수;
시작하다
server.readready (1) = 1 인 경우
시작하다
tempstrings : = tstringlist.create;
setolestrings (tempstrings, server.readfrom (1));
freadstartpos> 19 인 경우
if (fclearbuffertag = 0-server.testclearbuffertag (1))
시작하다
FreadStartpos : = 0;
fclearbuffertag : = server.TestClearBufferTag (1);
끝;
i : = freadstartpos to tempstrings.count-1 do
memo1.lines.add (tempstrings [i]);
freadstartpos : = tempstrings.count;
끝;
끝;
DCOM 기반 LAN 채팅방의 핵심 부분이 기본적으로 완료되었으며 모든 테스트는 비교적 매끄럽습니다. 또한 일정량의 동기화 처리가 발생했지만이 프로그램에는 추가 테스트와 일정량의 재건이 필요할 때 교착 상태 나 다른 라이브 잠금 장치가 여전히 발생할 수 있습니다.