Munculnya com terdistribusi (selanjutnya disebut DCOM) memberi kami kesempatan untuk dengan mudah membuat aplikasi terdistribusi; Aplikasi, pengembang hampir dapat mengabaikan MS-RPC) dan mengembangkan fungsi yang kuat dan kopling rendah (modul fungsional relatif independen, Ini telah memanfaatkan ide -ide OO dengan baik) dan mudah digunakan sistem komputasi terdistribusi.
Dalam artikel ini, kami bermaksud menggunakan DCOM untuk mengembangkan ruang obrolan LAN, tidak hanya sebagai penelitian teknis, tetapi sebenarnya saya percaya ini juga harus menjadi alat yang berguna. Pertama -tama, kita perlu memiliki pemahaman umum tentang fungsi ruang obrolan ini:
1. Setidaknya ruang obrolan ini harus memungkinkan beberapa pengguna LAN untuk mengobrol.
2. Seharusnya ada ruang sub-obrolan dengan banyak topik, dan pengguna dapat memilih untuk memasukkan ruang obrolan untuk mengobrol.
3. Klien harus sesederhana mungkin (tanpa mengkonfigurasi DCOM), dan sisi server perlu mengelola semua perilaku interaksi, mengelola jumlah ruang obrolan dan konfigurasi terkait, dan melakukan pekerjaan yang baik dalam pemantauan dan pencatatan sistem.
4. Perluas fungsi ruang obrolan (seperti fungsi percakapan yang tenang, emoji, dll.). Berdasarkan deskripsi fungsional di atas, setelah menganalisis masalah dengan cermat, kami merancang sketsa berikut:
Dalam artikel ini, kami ingin secara kasar mengimplementasikan inti dasar dari program ini, termasuk IChatManager, TchatroomManager, dan Tchatroom, untuk menyelesaikan server dengan fungsi paling dasar dan untuk melakukan deteksi klien sederhana. Fokus kami adalah di sisi server, karena akan menerapkan sebagian besar fungsi ruang obrolan, dan klien hanyalah program yang sangat kecil dan sederhana.
Karena ruang, kami hanya mencantumkan kode untuk bagian -bagian penting. Pertama, mari kita lihat seperti apa antarmuka ichatManager kami:
IChatManager = antarmuka (IDispatch)
['{E7CD7F0D-447F-497A-8C7B-1D80E748B67F}']
Prosedur Bicara (Konten Const: Luas; Destid: Integer);
// Klien berbicara dengan kamar yang ditunjuk, dan destid adalah nomor kamarnya
Fungsi ReadFrom (SourceID: Integer): Istrings;
// Klien membaca konten percakapan dari kamar yang ditentukan, SourceID adalah nomor kamar
fungsi readready (id: integer): byte;
// Pelanggan dapat memeriksa apakah kamar yang ditentukan sudah dapat membaca konten percakapan
Prosedur Connectroom (nama pengguna Const: widestring; roomID: integer);
// log pelanggan ke kamar yang ditunjuk
Prosedur Disconnectroom (nama pengguna Const: widestring; roomID: integer);
// Pelanggan keluar dari kamar yang ditentukan
fungsi testclearbuffertag (roomId: integer): integer;
// Tes Pelanggan Apakah zona buffer ruang yang ditentukan dibersihkan atau tidak
akhir;
Mari kita lihat bagian TChatManager dari kelas implementasi antarmuka:
jenis
TchatManager = kelas (tautoObject, ichatmanager)
terlindung
Fungsi ReadFrom (SourceID: Integer): Istrings;
// Di sini kita menggunakan tipe kompleks yang diperluas oleh Delphi, untuk membuat com mendukung ini
// ketik, delphi menyediakan antarmuka istrings
Prosedur Bicara (Konten Const: Luas; Destid: Integer);
fungsi readready (id: integer): byte;
// Digunakan untuk menyediakan klien untuk menanyakan apakah ruang yang ditentukan dapat dibaca, dan apakah buffer kamar yang ditentukan kosong
Prosedur Connectroom (nama pengguna Const: widestring; roomID: integer);
Safecall;
Prosedur Disconnectroom (nama pengguna Const: widestring; roomID: integer);
Safecall;
fungsi testclearbuffertag (roomId: integer): integer;
akhir;
Bagian Implementasi:
var
Temproom: Tchatroom;
Mulai
Temproom: = ChatroomManager.findroomById (SourceId);
sementara temproom.locked do
Mulai
// Lakukan Tidak Ada Yang Menunggu untuk Dibuka Kunci
akhir;
Getolestrings (temproom.oneread, hasil);
akhir;
Prosedur tchatManager.speakto (konten const: widestring; destid: integer);
var
Temproom: Tchatroom;
Mulai
Temproom: = ChatroomManager.FindroomById (DestId);
sementara temproom.locked do
Mulai
// Lakukan Tidak Ada Yang Menunggu untuk Dibuka Kunci
akhir;
Temproom.onespeak (konten);
akhir;
fungsi tchatmanager.readready (id: integer): byte;
var
Temproom: Tchatroom;
Mulai
Temproom: = chatroomManager.findroomById (id);
Jika temproom.canRead maka hasilnya: = 1 Hasil lain: = 0;
akhir;
Prosedur tchatmanager.connectroom (nama pengguna const: widestring;
RoomID: Integer);
// Klien masuk ke ruang yang ditentukan melalui antarmuka, dan tidak sepenuhnya diimplementasikan
var
Temproom: Tchatroom;
Mulai
Temproom: = ChatroomManager.FindroomById (RoomID);
Temproom.loginroom (nama pengguna);
akhir;
Prosedur tchatmanager.disconnectroom (nama pengguna const: widestring;
RoomID: Integer);
// Klien meninggalkan ruang yang ditentukan melalui antarmuka dan tidak sepenuhnya diimplementasikan
var
Temproom: Tchatroom;
Mulai
Temproom: = ChatroomManager.FindroomById (RoomID);
Temproom.leaveroom (nama pengguna);
akhir;
fungsi tchatmanager.testclearbuffertag (roomId: integer): integer;
var
Temproom: Tchatroom;
Mulai
Temproom: = ChatroomManager.FindroomById (RoomID);
Hasil: = Temproom.ClearBufferTag;
akhir;
Inisialisasi
TautoObjectFactory.create (Comserver, tchatmanager, class_chatmanager,
cimultiinstance, tmapartment);
akhir.
TChatroom yang paling penting terlihat seperti:
jenis
Tchatroom = kelas
Pribadi
Fbuffer: array [1..20] dari string;
Fbufferlength: integer;
Froomname: String;
Froomid: Integer;
Berbondong -bondong: boolean; // kunci sinkron, digunakan untuk menangani situasi di mana banyak orang mengirim percakapan pada saat yang sama
Fconnectcount: integer; // jumlah orang saat ini di dalam ruangan
Fclearbuffertag: integer;
// Nilai ini akan melonjak sekali setiap kali buffer dibersihkan, dan denyut nadi ini terdeteksi oleh klien
terlindung
Prosedur ClearBuffer; // Bersihkan buffer
Fungsi GetCanRead: Boolean;
publik
konstruktor buat (roomName: string; roomId: integer);
Prosedur OneSpeak (Konten: String); // Tambahkan konten obrolan ke buffer
Prosedur Loginroom (Nama Pengguna: String); // Lihat bagian implementasi dari komentar
Prosedur Leaveroom (nama pengguna: string); // lihat bagian implementasi dari komentar
Fungsi oneread: tstrings; // Baca catatan dari buffer
Properti terkunci: Boolean membaca berbondong -bondong; // readonly; // untuk deteksi ichatmanager
Properti CanRead: Boolean Read GetCanRead; // Tentukan apakah buffernya kosong, jika tidak itu tidak dapat dibaca
properti clearbuffertag: integer membaca fclearbuffertag;
akhir;
Implementasi TChatroom:
{Tchatroom}
konstruktor tchatroom.create (roomName: string; roomId: integer);
Mulai
Fbufferlength: = 0;
FconnectCount: = 0;
Fclearbuffertag: = 1;
Berbalik: = false;
Froomname: = RoomName;
Froomid: = roomId;
akhir;
Prosedur TChatroom.ClearBuffer;
var
I: Integer;
Mulai
/// Di sini Anda dapat mendeteksi bendera untuk menentukan apakah server perlu merekam setiap konten obrolan.
untuk i: = 1 hingga 20 lakukan
Fbuffer [i]: = '';
Fbufferlength: = 0;
FclearbufferTag: = 0-flearbuffertag;
akhir;
Prosedur tchatroom.onespeak (konten: string);
Mulai
Berbalik: = true;
Inc (FBufferLength);
Jika fBufferLength> 20 lalu
Mulai
ClearBuffer;
Inc (FBufferLength);
akhir;
Fbuffer [fbufferlength]: = konten;
Berbalik: = false;
akhir;
fungsi tchatroom.oneread: tstrings;
var
Fstrings: tstrings;
I: Integer;
Mulai
Berbalik: = true;
Fstrings: = tStringList.create;
untuk i: = 1 ke fbufferlength do
Fstrings.add (fbuffer [i]);
Hasil: = FStrings;
Berbalik: = false;
akhir;
fungsi tchatroom.getCanRead: boolean;
Mulai
Hasil: = false;
Jika fBufferLength> 0 maka hasilnya: = true;
akhir;
Prosedur tChatroom.Loginroom (nama pengguna: string);
// Acara Ruang Obrolan Login Pengguna tidak sepenuhnya diimplementasikan di sini
Mulai
Inc (fconnectcount);
akhir;
Prosedur tchatroom.leaveroom (nama pengguna: string);
// Pengguna meninggalkan acara ruang obrolan, tidak sepenuhnya diimplementasikan di sini
Mulai
Dec (fconnectcount);
akhir;
Bagian penting terakhir dari sisi server tchatroommanager:
jenis
TchatroomManager = kelas
Pribadi
Obrolan: Array TChatroom;
publik
konstruktor membuat;
fungsi findroomById (id: integer): tchatroom;
akhir;
Bagian Implementasi:
{TchatroomManager}
konstruktor tchatroommanager.create;
var
I, RoomCount: Integer;
RoomNames: tstrings; // roomName adalah nama ruang obrolan di file konfigurasi
Mulai
RoomCount: = 1;
// Di sini kita akan membaca beberapa ruang obrolan dari file konfigurasi.
RoomNames: = tStringList.create;
RoomNames.Add ('testroom'); // Kalimat ini akan digantikan oleh bacaan akhir dari file konfigurasi.
setLength (ruang obrolan, roomcount);
untuk i: = 1 ke roomcount do
Chatroom [i]: = tchatroom.create (roomNames [i-1], i);
akhir;
fungsi tchatroommanager.findroomById (id: integer): tchatroom;
// Fungsi ini dipanggil oleh antarmuka IchhatManager, karena versi final antarmuka akan diberikan kepada pelanggan
// Fungsi mendapatkan daftar kamar sehingga klien mengetahui id kamarnya
Mulai
Hasil: = Chatroom [ID];
akhir;
Inisialisasi
ChatroomManager: = tchatroomManager.create;
akhir.
Setelah bagian inti utama dari sisi server selesai, kami mengkonfigurasi konfigurasi DCOM sisi server dan dapat mengembangkan klien sederhana untuk pengujian: (meskipun klien sesederhana mungkin, kami tidak perlu mengkonfigurasi DCOM, tetapi kami masih Perlu menyalin Jenis Sisi Server File Perpustakaan .TLB hanya dapat dikembangkan dan digunakan setelah mendaftarkan klien.
Pada klien kami hanya mencantumkan dua fungsi yang relatif penting, dan sisanya dihilangkan.
Prosedur TFORM1.BUTTON1CLICK (Pengirim: Tobject);
// klik tombol1 dan "katakan" konten edit
Mulai
Server.speakto (edit1.text, 1);
akhir;
Prosedur TFORM1.TIMER1TIMER (Pengirim: Tobject);
// Minta konten percakapan dari server sesekali, dan saya mengaturnya ke 1,5 detik
var
Tempstrings: Tstrings;
I: Integer;
Mulai
Jika server.readready (1) = 1 lalu
Mulai
Tempsstrings: = tStringList.create;
Setolestrings (Tempsstrings, server.readfrom (1));
Jika freadstartpos> 19 lalu
if (fclearbuffertag = 0-server.testclearbuffertag (1)) lalu
Mulai
Freadstartpos: = 0;
FclearbufferTag: = server.testclearbuffertag (1);
akhir;
untuk i: = freadstartpos to tempstrings.count-1 do
Memo1.lines.add (Tempstrings [i]);
Freadstartpos: = Tempstrings.count;
akhir;
akhir;
Bagian inti dari ruang obrolan LAN berbasis DCOM pada dasarnya telah selesai, dan semua tes relatif lancar. juga melakukannya.