Membuat Aplikasi Multiplayer Menggunakan Directplay-Pada artikel kali ini, admin akan memakai istilah aplikasi multiplayer untuk mengacu pada jenis aplikasi yang dipakai oleh dua atau lebih user pada komputer-komputer yang terhubung melalui jaringan. Kaprikornus selain game multiplayer online, aplikasi chat juga termasuk kategori ini. Penulis akan menitikberatkan pada klarifikasi langkah-langkah dasar membuat aplikasi multiplayer memanfaatkan DirectPlay.
Apa Itu DirectPlay?
DirectPlay yang merupakan bab DirectX, yaitu Application Programming Interface (API) yang khusus diciptakan untuk menyederhanakan pengembangan aplikasi jaringan menyerupai game multiplayer atau aplikasi chat pada operating system Windows. DirectPlay mengisolasi aplikasi multiplayer dari kerumitan jaringan di bawahnya serta menyederhanakan implementasi beberapa hal berikut :
- Menciptakan dan administrasi sesi permainan.
- Manajemen pemain dan grup dalam sesi.
- Pengiriman data antarpemain dalam sesi.
- Koneksi melalui lobby. Komunikasi bunyi antara pemain dalam sesi.
Untuk artikel ini, penulis hanya memfokuskan pembahasan pada tiga poin teratas.
Service Provider.
DirectPlay menyembunyikan detail koneksi jaringan dari aplikasi. Abstraksi ini memungkinkan tiap aplikasi berkomunikasi dengan cara yang seragam tanpa peduli tipe jaringan yang terlibat, termasuk perbedaan perangkat keras dan perangkat lunak jaringan. Koneksi jaringan gotong royong dibentuk melalui service provider.
DirectPlay menyertakan service provider untuk protokol TCP/IP, IPX, modem, dan serial. Service provider bertanggung jawab terhadap detail cara komunikasi untuk masing-masing protokol. Pada ketika inisialisasi, aplikasi harus menentukan service provider yang dipergunakan. Untuk detail bagaimana menentukan service provider, silakan baca “Inisialisasi Alamat”.
Arsitektur Jaringan.
DirectPlay mendukung dua model koneksi jaringan, yakni model peer-to-peer dan client-server. Sobat harus menentukan dari awal, model mana yang cocok untuk aplikasi sobat. Model peer-to-peer dan client-server masing-masing dibungkus dalam interface IDirectPlay8Peer, IDirectPlay8Client, dan IDirectPlay8Server.
Peer-to-Peer.
Pada model peer-to-peer, tiap komputer terhubung ke komputer lain dalam sebuah sesi yang sama, di mana tiap komputer (peer) sanggup saling berkomunikasi eksklusif (Lihat gambar dibawah ini).
Tiap peer dalam sebuah sesi bertanggung jawab menyimpan status game dan status player lain dalam sesi. Tiap kali sebuah peer perlu melaksanakan update status game, info perubahan tersebut harus dikirim ke semua komputer lain yang ada di sesi tersebut, sehingga masing-masing peer sanggup melaksanakan sinkronisasi status game.
Pada model peer-to-peer, terdapat sebuah peer yang bertanggung jawab sebagai host, biasanya peer ini yaitu yang membuat sesi. Host berfungsi menangani peer yang hendak bergabung atau meninggalkan sesi dan juga sebagai pengelola sesi. Status sebagai host sanggup ditransfer ke peer lain bila host meninggalkan sebuah sesi, dengan syarat sesi tersebut dibentuk dengan kemampuan untuk melaksanakan migrasi host.
Tanpa kemampuan ini, bila sebuah host meninggalkan sesi permainan, sesi tersebut juga akan dihentikan. Walaupun dalam sebuah sesi terdapat sebuah peer yang bertindak sebagai host, tiap peer sanggup berkomunikasi dengan peer lain tanpa melalui host.
Keuntungan.
- Lebih sederhana alasannya tidak perlu menyediakan instruksi aplikasi yang berbeda. Tiap peer mempunyai instruksi aplikasi yang sama dengan peer lain, termasuk peer yang bertindak sebagai host.
Kerugian.
- Jika tidak diimplementasikan dengan benar, model ini berpotensi menghambat kinerja, terutama alasannya tiap peer yang bergabung menyebabkan jumlah trafik jaringan juga akan meningkat sangat drastis sehingga hanya cocok untuk aplikasi multiplayer dengan jumlah pemain sedikit.
- Keamanan lebih sulit dikontrol alasannya tiap peer sanggup berkomunikasi eksklusif dengan peer lain.
Client-Server.
Pada model client-server, satu komputer (atau lebih pada game online berskala besar) bertindak sebagai server dan komputer lain (client) harus terhubung ke server untuk bisa bergabung dalam sebuah sesi permainan (Lihat gambar dibawah ini).
Tiap client hanya berkomunikasi dengan server dan tidak dengan klien lain. Ketika klien hendak melaksanakan update status game, klien mengirimkan pesan ke server. Server kemudian mendistribusikan pesan dari klien ke semua klien lain dalam satu sesi.
Kode aplikasi untuk klien dan server biasanya dipisahkan. Aplikasi untuk server biasanya menangani semua administrasi status game namun tanpa fitur grafis dan suara, sedangkan aplikasi klien hanya berfungsi menyusun tampilan interface pengguna (user-interface game), mendapatkan input dari pengguna dan fitur bunyi dan tentu saja mengatur supaya status game sinkron dengan status game yang ada di server.
Keuntungan.
- Model client-server menghasilkan skalabilitas yang lebih baik. Jika jumlah klien bertambah, jumlah trafik data naik secara linier alasannya tiap klien hanya berkomunikasi dengan server.
- Karena aplikasi server dan client terpisah, server sanggup dibentuk memakai sistem yang berdaya tinggi dan fokus ke bagaimana menangani pemrosesan logika, sedangkan aplikasi klien bisa dibentuk fokus pada grafik dan bunyi yang menawan.
- Keamanan lebih baik alasannya tiap klien hanya berkomunikasi dengan server, sehingga lebih gampang dikontrol.
- Memudahkan penyusunan dunia dalam game, alasannya terpusat di server. Update dan bug fix terhadap instruksi yang menyusun game lebih mudah.
Kerugian.
- Butuh perjuangan dan perencanaan lebih panjang.
- Lebih rumit alasannya aplikasi harus dibentuk terpisah, untuk server dan client.
Bekerja dengan Pemain dan Grup.
Pemain.
Istilah pemain (player) pada pemrograman DirectPlay mengacu pada koneksi tunggal yang terhubung ke komputer lain melalui jaringan. Sebuah komputer sanggup terdiri atas satu atau lebih pemain, bahkan sebuah server oleh DirectPlay juga dianggap sebagai pemain.
Tiap pemain yang tergabung dalam sebuah sesi permainan, diidentifikasi memakai pengenal bertipe DPNID (atau TDPNID di header konversi Delphi). Tipe ini sejatinya yaitu tipe Dword. Pengenal ini dihasilkan oleh DirectPlay ketika seorang pemain tergabung ke sebuah sesi permainan dan akan diinformasikan semua pemain yang tergabung dalam sesi permainan. Sobat bisa memakai pengenal ini untuk meminta data rinci seorang pemain menyerupai nama dan data terkait pemain tersebut dan juga untuk mengirim data ke pemain tersebut.
Grup.
Untuk game dengan skala lebih besar di mana jumlah pemain yang terhubung sangat banyak, teman mungkin perlu membuat grup-grup untuk mengelompokkan pemain guna memudahkan penanganannya. Penggunaan grup, sedikit mempermudah proses pengiriman pesan untuk sekelompok pemain.
Sobat bisa mengirim pesan ke sebuah grup dari pada harus mengirim pesan tersebut satu per satu ke tiap pemain. Tidak ada batasan berapa grup yang sanggup teman buat atau berapa pemain yang sanggup teman kelompokkan dalam satu grup.
Sebuah grup juga sanggup berisi grup lain menyerupai terlihat pada gmbar dibawah ini. Pemain sanggup juga berdiri sendiri, tidak tergabung dalam grup manapun.
Globally Unique Identifier (GUID).
Globally Unique Identifier (GUID) sesuai namanya yaitu pengenal yang unik secara global yang tersusun atas string alfanumerik. Karena besarnya ukuran data dan kompleksnya algoritma penyusunan GUID, GUID dijamin unik secara global. Jika teman membuat GUID baru, dijamin tidak ada orang lain yang akan menghasilkan GUID yang sama.
GUID pada DirectPlay dipakai untuk identifikasi aplikasi. Jika membuat aplikasi baru, teman perlu membuat GUID gres untuk aplikasi tersebut. Sobat bisa membuat GUID pada ketika runtime, namun hal ini tidak perlu. teman bisa menghasilkan GUID di Delphi dengan menekan kombinasi keyboard shortcut Shift+Ctrl+G.
GUID pada DirectPlay dipakai untuk identifikasi aplikasi. Jika membuat aplikasi baru, teman perlu membuat GUID gres untuk aplikasi tersebut. Sobat bisa membuat GUID pada ketika runtime, namun hal ini tidak perlu. teman bisa menghasilkan GUID di Delphi dengan menekan kombinasi keyboard shortcut Shift+Ctrl+G.
Operasi Asynchronous dan Synchronous.
Operasi yang teman kerjakan memakai DirectPlay sanggup dibentuk asynchronous atau synchronous. Pada operasi asynchronous, DirectPlay akan menjalankan operasi yang diminta dan segera mengembalikan kontrol ke aplikasi tanpa menunggu operasi tersebut selesai. DirectPlay akan mengembalikan nilai DPNSUCCESS_PENDING pada operasi asynchronous yang belum selesai.
Operasi asynchronous membuat aplikasi lebih responsif, namun prosesnya lebih rumit. Pada operasi synchronous, DirectPlay akan menunggu operasi hingga selesai gres kemudian mengembalikan kontrol ke aplikasi. Selama menunggu operasi selesai, aplikasi kita akan terlihat “hang” dan tidak responsif, namun prosesnya lebih sederhana.
Operasi yang teman kerjakan memakai DirectPlay sanggup dibentuk asynchronous atau synchronous. Pada operasi asynchronous, DirectPlay akan menjalankan operasi yang diminta dan segera mengembalikan kontrol ke aplikasi tanpa menunggu operasi tersebut selesai. DirectPlay akan mengembalikan nilai DPNSUCCESS_PENDING pada operasi asynchronous yang belum selesai.
Operasi asynchronous membuat aplikasi lebih responsif, namun prosesnya lebih rumit. Pada operasi synchronous, DirectPlay akan menunggu operasi hingga selesai gres kemudian mengembalikan kontrol ke aplikasi. Selama menunggu operasi selesai, aplikasi kita akan terlihat “hang” dan tidak responsif, namun prosesnya lebih sederhana.
Isu ihwal Pengiriman.
Data Secara default, DirectPlay tidak menjamin data yang teman kirim akan diterima oleh penerima. Paket data mungkin hilang pada ketika dikirimkan ke jaringan dan ini sering kali terjadi. Untuk data yang tidak boleh hilang, teman sanggup menentukan memakai pengiriman terjamin. Pada mode pengiriman terjamin, selama pemain masih terkoneksi, DirectPlay akan berusaha mengirim ulang paket-paket data yang drop hingga data lengkap terkirim.
Sisi buruknya, performa menurun alasannya membutuhkan waktu lebih banyak, terutama bila banyak paket data yang hilang. Pengiriman data juga tidak dienkripsi. Sobat sanggup juga mengenkripsi data yang teman kirim untuk mengamankan data tersebut. Enkripsi data juga menurunkan performa alasannya DirectPlay harus melaksanakan enkripsi data ketika mengirim dan dekripsi ketika menerimanya. Untungnya bagi kita, untuk memastikan data terkirim dan mengenkripsi data sangat mudah. Hanya problem mengatur flag-flag yang sesuai.
Data Secara default, DirectPlay tidak menjamin data yang teman kirim akan diterima oleh penerima. Paket data mungkin hilang pada ketika dikirimkan ke jaringan dan ini sering kali terjadi. Untuk data yang tidak boleh hilang, teman sanggup menentukan memakai pengiriman terjamin. Pada mode pengiriman terjamin, selama pemain masih terkoneksi, DirectPlay akan berusaha mengirim ulang paket-paket data yang drop hingga data lengkap terkirim.
Sisi buruknya, performa menurun alasannya membutuhkan waktu lebih banyak, terutama bila banyak paket data yang hilang. Pengiriman data juga tidak dienkripsi. Sobat sanggup juga mengenkripsi data yang teman kirim untuk mengamankan data tersebut. Enkripsi data juga menurunkan performa alasannya DirectPlay harus melaksanakan enkripsi data ketika mengirim dan dekripsi ketika menerimanya. Untungnya bagi kita, untuk memastikan data terkirim dan mengenkripsi data sangat mudah. Hanya problem mengatur flag-flag yang sesuai.
Inisialisasi Peer-to-peer.
Karena topik DirectPlay ini cukup luas, di artikel ini, admin akan membatasi pada klarifikasi bagaimana membuat sesi peer-to-peer. Untuk membuat IDirectPlay8Peer, teman memakai CoCreateInstance() yang dideklarasi di unit ActiveX.pas. Sebelum memanggil CoCreateInstance(), teman perlu memastikan COM telah diinisialisasi dengan CoInitialize(). Contoh bagaimana mendapatkan instance IDirectPlay8Peer yaitu menyerupai Listing 1.
Jika sukses, FPeerNet, menyerupai yang tercantum pada Listing 1, akan diisi dengan alamat ke instance IDirectPlay8Peer. Jika gagal, maka FPeerNet berisi nil. Bila sukses, teman bisa melanjutkan proses inisialisasi peer-to-peer dengan memanggil metode Initialize() milik IDirectPlay8Peer (Listing 2).
Fungsi ini mempunyai kegunaan untuk mendaftarkan fungsi callback yang akan dipanggil tiap kali instance IDirectPlay8Peer mendapatkan pesan. Parameter pvUserContext yaitu data yang akan dikirimkan melalui message handler yang alamatnya ada pada parameter pfn. dwFlags yaitu flag inisialisasi menyerupai yang tercantum pada gambar dibawah ini.
Karena topik DirectPlay ini cukup luas, di artikel ini, admin akan membatasi pada klarifikasi bagaimana membuat sesi peer-to-peer. Untuk membuat IDirectPlay8Peer, teman memakai CoCreateInstance() yang dideklarasi di unit ActiveX.pas. Sebelum memanggil CoCreateInstance(), teman perlu memastikan COM telah diinisialisasi dengan CoInitialize(). Contoh bagaimana mendapatkan instance IDirectPlay8Peer yaitu menyerupai Listing 1.
Jika sukses, FPeerNet, menyerupai yang tercantum pada Listing 1, akan diisi dengan alamat ke instance IDirectPlay8Peer. Jika gagal, maka FPeerNet berisi nil. Bila sukses, teman bisa melanjutkan proses inisialisasi peer-to-peer dengan memanggil metode Initialize() milik IDirectPlay8Peer (Listing 2).
Fungsi ini mempunyai kegunaan untuk mendaftarkan fungsi callback yang akan dipanggil tiap kali instance IDirectPlay8Peer mendapatkan pesan. Parameter pvUserContext yaitu data yang akan dikirimkan melalui message handler yang alamatnya ada pada parameter pfn. dwFlags yaitu flag inisialisasi menyerupai yang tercantum pada gambar dibawah ini.
Message Callback Parameter pfn pada Listing 2 mendeskripsikan fungsi callback yang dipakai untuk komunikasi antara DirectPlay dan aplikasi kita. Parameter pfn bertipe TFNDPNMessageHandler atau PFNDPNMESSAGEHANDLER, deklarasinya yaitu menyerupai Listing3.
Karena semua pesan yang dikirim jaringan akan melalui callback ini, fungsi callback ini sangat vital menentukan performa aplikasi sobat. Sangat tidak disarankan untuk meletakkan instruksi yang eksekusinya lambat dalam callback ini. Parameter pvUserContext pada Listing 3 yaitu pointer ke data milik aplikasi kita. Isi parameter ini sama dengan isi parameter pvUserContext yang kita set pada ketika pemanggilan Initialize() (Listing 2).
Parameter dwMessageType yaitu tipe pesan yang dikirim DirectPlay ke aplikasi kita. Tabel 2 berisi tipe-tipe pesan yang dikirim ke aplikasi. Kita akan membahas bagaimana meng-handle beberapa pesan umum pada artikel bab ke-3 di bab “Menangani Pesan Jaringan”. Parameter pMessage yaitu pointer yang menunjuk ke struktur data yang terkait dengan sebuah pesan.
Penamaan struktur data terkait sebuah pesan, sama dengan nama tipe pesannya, kecuali bahwa DPN_MSGID diganti dengan DPNMSG. Contoh, pesan DPN_MSGID_CREATE_PLAYER terkait dengan struktur data DPNMSG_CREATE_PLAYER. Sesuai konvensi di Delphi, struktur data tersebut dinamai ulang menjadi TDPNMsgCreatePlayer. Membuat callback untuk menangani pesan dari DirectPlay cukup mudah.
Sobat tinggal mendeklarasikan sebuah fungsi bertipe TFNDPNMessageHandler dan memproses masing-masing data menurut tipe pesannya. Callback ini, meskipun teman yang membuat implementasinya, tidak dipanggil oleh aplikasi teman secara langsung. DirectPlay yang akan memanggil callback ini ketika pesan dari jaringan perlu diproses aplikasi.
Yang teman harus pastikan ketika menyusun implementasinya yaitu fungsi tersebut harus berupa fungsi biasa (bukan fungsi bab dalam sebuah kelas), alasannya cara melewatkan parameternya berbeda, dan jangan lupa memakai direktif stdcall. Kecuali untuk tipe pesan tertentu, biasanya teman cukup mengembalikan nilai S_OK sebagai return value.
Contohnya deklarasi callback menyerupai pada Listing 4. Fungsi callback akan dipanggil dalam thread yang terpisah dari thread aplikasi, sehingga fungsi callback ini harus threadsafe. Sobat mungkin perlu membuat prosedur untuk mengontrol terusan terhadap resource dalam callback ini.
Karena semua pesan yang dikirim jaringan akan melalui callback ini, fungsi callback ini sangat vital menentukan performa aplikasi sobat. Sangat tidak disarankan untuk meletakkan instruksi yang eksekusinya lambat dalam callback ini. Parameter pvUserContext pada Listing 3 yaitu pointer ke data milik aplikasi kita. Isi parameter ini sama dengan isi parameter pvUserContext yang kita set pada ketika pemanggilan Initialize() (Listing 2).
Parameter dwMessageType yaitu tipe pesan yang dikirim DirectPlay ke aplikasi kita. Tabel 2 berisi tipe-tipe pesan yang dikirim ke aplikasi. Kita akan membahas bagaimana meng-handle beberapa pesan umum pada artikel bab ke-3 di bab “Menangani Pesan Jaringan”. Parameter pMessage yaitu pointer yang menunjuk ke struktur data yang terkait dengan sebuah pesan.
Penamaan struktur data terkait sebuah pesan, sama dengan nama tipe pesannya, kecuali bahwa DPN_MSGID diganti dengan DPNMSG. Contoh, pesan DPN_MSGID_CREATE_PLAYER terkait dengan struktur data DPNMSG_CREATE_PLAYER. Sesuai konvensi di Delphi, struktur data tersebut dinamai ulang menjadi TDPNMsgCreatePlayer. Membuat callback untuk menangani pesan dari DirectPlay cukup mudah.
Sobat tinggal mendeklarasikan sebuah fungsi bertipe TFNDPNMessageHandler dan memproses masing-masing data menurut tipe pesannya. Callback ini, meskipun teman yang membuat implementasinya, tidak dipanggil oleh aplikasi teman secara langsung. DirectPlay yang akan memanggil callback ini ketika pesan dari jaringan perlu diproses aplikasi.
Yang teman harus pastikan ketika menyusun implementasinya yaitu fungsi tersebut harus berupa fungsi biasa (bukan fungsi bab dalam sebuah kelas), alasannya cara melewatkan parameternya berbeda, dan jangan lupa memakai direktif stdcall. Kecuali untuk tipe pesan tertentu, biasanya teman cukup mengembalikan nilai S_OK sebagai return value.
Contohnya deklarasi callback menyerupai pada Listing 4. Fungsi callback akan dipanggil dalam thread yang terpisah dari thread aplikasi, sehingga fungsi callback ini harus threadsafe. Sobat mungkin perlu membuat prosedur untuk mengontrol terusan terhadap resource dalam callback ini.
Isu Multiple Thread DirectPlay memakai banyak thread untuk menangani message yang diterima dari jaringan. Pada ketika kita melaksanakan inisialisasi objek peer-to-peer dan menentukan callback yang akan dipanggil DirectPlay, DirectPlay akan membuat sebuah thread baru, terpisah dari thread aplikasi utama, di mana callback akan dipanggil tiap kali ada pesan dari jaringan harus diproses aplikasi kita.
Manajemen thread-thread tersebut ditangani oleh DirectPlay dan untuk tingkat tertentu, transparan bagi aplikasi kita. Namun alasannya thread utama aplikasi dan thread yang diciptakan DirectPlay berada dalam satu proses, maka thread-thread tersebut juga berada dalam memory yang sama. Oleh alasannya itu, threadthread tersebut harus mengembangkan resource di memory ini.
Hal ini bisa menjadi masalah. Katakanlah sobat mempunyai dua thread yang harus mengakses sebuah variabel yang sama. Jika sebuah thread tersebut sedang membaca variabel tersebut dan thread lainnya berusaha menulis data ke variabel yang sama pada ketika bersamaan, akhirnya mungkin tidak menyerupai yang diinginkan.
Untuk memecahkan problem ini, kita bisa memakai critical section untuk melindungi suatu resource supaya tidak sanggup diakses oleh thread lain. Tiap kali sebuah thread hendak mengeksekusi bab instruksi yang mengakses resource yang juga diakses oleh thread lain, terusan ke resource tersebut kita blok dengan menguncinya.
Selama masih kita kunci dengan critical section, thread sanggup dengan bebas memanipulasi isi resource tersebut. Thread lain yang hendak mengunci bab instruksi yang ditandai sebagai critical section harus menunggu hingga critical section dibebaskan. Segera sehabis selesai, penguncian kita buka, sehingga thread lain sanggup memakai resource tersebut.
Untuk masuk dan keluar critical section, kita memakai EnterCriticalSection() dan LeaveCriticalSection() (Listing 5). Variabel csData pada Listing 5 bertipe TRTLCriticalSection. Sebelum digunakan, csData harus diinisialiasasi memakai InitializeCriticalSection(). Setelah critical section tidak lagi dibutuhkan, bisa dihapus dengan memanggil DeleteCriticalSection().
Apa yang instruksi teman lakukan di antara pemanggilan EnterCriticalSection() dan LeaveCriticalSection() sebisa mungkin dipersingkat. Jika tidak, critical section bisa menghambat sanksi thread lain sehingga menyebabkan turunnya performa aplikasi secara keseluruhan. Hal lain yang perlu dihindari yaitu meletakkan critical section dalam critical section lain.
Sobat sebaiknya menghindari pemanggilan EnterCriticalSection() pada Listing 6. Kode pada Listing 6 sangat berpeluang menyebabkan deadlock. Jika thread A mencoba memasuki critical section csData2 yang sebelumnya sudah dimasuki thread B dan pada ketika bersamaan thread B berusaha memasuki critical section csData yang sebelumnya sudah dimasuki thread A, kedua thread akan saling mengunci sehingga terjadilah deadlock.
Manajemen thread-thread tersebut ditangani oleh DirectPlay dan untuk tingkat tertentu, transparan bagi aplikasi kita. Namun alasannya thread utama aplikasi dan thread yang diciptakan DirectPlay berada dalam satu proses, maka thread-thread tersebut juga berada dalam memory yang sama. Oleh alasannya itu, threadthread tersebut harus mengembangkan resource di memory ini.
Hal ini bisa menjadi masalah. Katakanlah sobat mempunyai dua thread yang harus mengakses sebuah variabel yang sama. Jika sebuah thread tersebut sedang membaca variabel tersebut dan thread lainnya berusaha menulis data ke variabel yang sama pada ketika bersamaan, akhirnya mungkin tidak menyerupai yang diinginkan.
Untuk memecahkan problem ini, kita bisa memakai critical section untuk melindungi suatu resource supaya tidak sanggup diakses oleh thread lain. Tiap kali sebuah thread hendak mengeksekusi bab instruksi yang mengakses resource yang juga diakses oleh thread lain, terusan ke resource tersebut kita blok dengan menguncinya.
Selama masih kita kunci dengan critical section, thread sanggup dengan bebas memanipulasi isi resource tersebut. Thread lain yang hendak mengunci bab instruksi yang ditandai sebagai critical section harus menunggu hingga critical section dibebaskan. Segera sehabis selesai, penguncian kita buka, sehingga thread lain sanggup memakai resource tersebut.
Untuk masuk dan keluar critical section, kita memakai EnterCriticalSection() dan LeaveCriticalSection() (Listing 5). Variabel csData pada Listing 5 bertipe TRTLCriticalSection. Sebelum digunakan, csData harus diinisialiasasi memakai InitializeCriticalSection(). Setelah critical section tidak lagi dibutuhkan, bisa dihapus dengan memanggil DeleteCriticalSection().
Apa yang instruksi teman lakukan di antara pemanggilan EnterCriticalSection() dan LeaveCriticalSection() sebisa mungkin dipersingkat. Jika tidak, critical section bisa menghambat sanksi thread lain sehingga menyebabkan turunnya performa aplikasi secara keseluruhan. Hal lain yang perlu dihindari yaitu meletakkan critical section dalam critical section lain.
Sobat sebaiknya menghindari pemanggilan EnterCriticalSection() pada Listing 6. Kode pada Listing 6 sangat berpeluang menyebabkan deadlock. Jika thread A mencoba memasuki critical section csData2 yang sebelumnya sudah dimasuki thread B dan pada ketika bersamaan thread B berusaha memasuki critical section csData yang sebelumnya sudah dimasuki thread A, kedua thread akan saling mengunci sehingga terjadilah deadlock.
Inisialiasasi Alamat dan Memilih Service Provider.
Untuk bisa berkomunikasi dengan komputer-komputer lain, tiap komputer harus mempunyai alamat unik. Alamat komputer di mana aplikasi berjalan disebut sebagai alamat device (device address), sedangkan untuk alamat komputer yang hendak dituju diistilahkan sebagai alamat host (host address).
DirectPlay memakai string URL untuk mengacu pada alamat suatu komputer yang dibungkus dalam interface IDirectPlay8Address. Untuk memanipulasi URL, sobat sanggup memakai metode-metode yang disediakan interface ini.
Listing 7 berisi pola bagaimana mendapatkan alamat instance IDirectPlay8Address. Kegunaan lain interface ini yaitu untuk menentukan service provider yang diinginkan memakai metode SetSP().
Deklarasinya yaitu menyerupai Listing 8. pguidSP berisi GUID service provider. Sobat bisa memakai nilai-nilai yang sudah tertentu menyerupai tercantum pada Tabel 3.
Untuk tiap-tiap service provider, teman mungkin perlu mengubah beberapa parameter terkait protokol yang dipilih.
Untuk TCP/IP atau IPX, teman mungkin perlu mengubah port yang digunakan, atau untuk koneksi melalui serial, teman mungkin ingin mengubah baud rate, stop bits, parity, dan fl ow control perangkat serial. Untuk mengubah parameter service provider, teman memakai metode AddComponent() milik interface IDirectPlay8Address (Listing 9). pwszName berisi nama komponen yang akan ditambahkan.
Jika sudah ada, nilainya akan diubah. Sobat bisa memakai beberapa nilai-nilai terdefinisi menyerupai pada Tabel 4.
lpvData berisi pointer ke data. dwDataSize berisi ukuran data lpvData, sedangkan tipenya ditentukan parameter dwDataType. Tabel 5 berisi daftar tipe-tipe data. Listing 10 berisi pola bagaimana mengubah port untuk TCP/IP.
FAddrNet diasumsikan bertipe IDirectPlay8Address dan FPort yaitu variabel bertipe Dword yang menyimpan data nomor port yang diinginkan.
Untuk bisa berkomunikasi dengan komputer-komputer lain, tiap komputer harus mempunyai alamat unik. Alamat komputer di mana aplikasi berjalan disebut sebagai alamat device (device address), sedangkan untuk alamat komputer yang hendak dituju diistilahkan sebagai alamat host (host address).
DirectPlay memakai string URL untuk mengacu pada alamat suatu komputer yang dibungkus dalam interface IDirectPlay8Address. Untuk memanipulasi URL, sobat sanggup memakai metode-metode yang disediakan interface ini.
Listing 7 berisi pola bagaimana mendapatkan alamat instance IDirectPlay8Address. Kegunaan lain interface ini yaitu untuk menentukan service provider yang diinginkan memakai metode SetSP().
Deklarasinya yaitu menyerupai Listing 8. pguidSP berisi GUID service provider. Sobat bisa memakai nilai-nilai yang sudah tertentu menyerupai tercantum pada Tabel 3.
Untuk tiap-tiap service provider, teman mungkin perlu mengubah beberapa parameter terkait protokol yang dipilih.
Untuk TCP/IP atau IPX, teman mungkin perlu mengubah port yang digunakan, atau untuk koneksi melalui serial, teman mungkin ingin mengubah baud rate, stop bits, parity, dan fl ow control perangkat serial. Untuk mengubah parameter service provider, teman memakai metode AddComponent() milik interface IDirectPlay8Address (Listing 9). pwszName berisi nama komponen yang akan ditambahkan.
Jika sudah ada, nilainya akan diubah. Sobat bisa memakai beberapa nilai-nilai terdefinisi menyerupai pada Tabel 4.
lpvData berisi pointer ke data. dwDataSize berisi ukuran data lpvData, sedangkan tipenya ditentukan parameter dwDataType. Tabel 5 berisi daftar tipe-tipe data. Listing 10 berisi pola bagaimana mengubah port untuk TCP/IP.
FAddrNet diasumsikan bertipe IDirectPlay8Address dan FPort yaitu variabel bertipe Dword yang menyimpan data nomor port yang diinginkan.
Mengatur Deskripsi Peer.
Informasi mengenai peer menyerupai nama dan data yang kita asosiasikan dengan suatu player perlu diset untuk identifi kasi bagi peer lain. Sobat harus mengatur deskripsi peer sebelum membuat sesi atau bergabung ke sesi yang sudah ada. Untuk mengatur deskripsi peer, teman memanggil SetPeerInfo() milik IDirectPlay8Peer. Deklarasi fungsi ini ada pada Listing 11.
Deklarasi tipe TDPNPlayerInfo tercantum pada Listing 12. Field-fi eld tipe data ini yaitu :
2. DPNINFO_DATA., field pvData berisi data yang valid.
Informasi mengenai peer menyerupai nama dan data yang kita asosiasikan dengan suatu player perlu diset untuk identifi kasi bagi peer lain. Sobat harus mengatur deskripsi peer sebelum membuat sesi atau bergabung ke sesi yang sudah ada. Untuk mengatur deskripsi peer, teman memanggil SetPeerInfo() milik IDirectPlay8Peer. Deklarasi fungsi ini ada pada Listing 11.
- dwSize, ukuran struktur data ini. Field ini harus teman isi dengan sizeof(TDPNPlayerInfo).
- dwInfoFlags, flag berisi data apa yang dikandung. Ada dua nilai untuk flag ini :
2. DPNINFO_DATA., field pvData berisi data yang valid.
- pwszName, nama player dalam format Unicode.
- pvData, data player.
- dwDataSize, ukuran yang tersimpan dalam pvData.
- dwPlayerFlags, flag status player apakah sebagai host atau player biasa. Isinya salah satu dari nilai berikut :
2. DPNPLAYER_HOST, player yang juga bertugas sebagai host.
Contoh bagaimana mengatur nama player sanggup teman pelajari di Listing 13. Seperti biasa, kita perlu mengisi struktur data ini dengan nol, kemudian mengisi field dwSize dengan ukuran tipe TDPNPlayerInfo. Variabel PlayerName diasumsikan bertipe string berisi nama player, wName bertipe widestring.
Di sini kita perlu mengonversi string ke widestring supaya sanggup kita typecast ke PWideChar. Untuk mendapatkan nama player dengan akurat, teman perlu memanggil GetPeerInfo() dua kali. Pertama untuk mendapatkan ukuran data player dan kedua untuk mengambil data player. Listing 14 berisi pola bagaimana mendapatkan nama player memakai ID player (DPNID).
Di sini kita perlu mengonversi string ke widestring supaya sanggup kita typecast ke PWideChar. Untuk mendapatkan nama player dengan akurat, teman perlu memanggil GetPeerInfo() dua kali. Pertama untuk mendapatkan ukuran data player dan kedua untuk mengambil data player. Listing 14 berisi pola bagaimana mendapatkan nama player memakai ID player (DPNID).
Ringkasan DirectPlay memungkinkan teman membangun aplikasi jaringan terutama game online multiplayer dengan lebih mudah. Membebaskan teman dari detail perbedaan protokol dan perangkat keras jaringan yang menghubungkan masing-masing komputer sehingga bisa fokus ke kecerdikan aplikasi.
Di di bab pertama artikel ini, teman sudah memperoleh info ihwal konsep dasar DirectPlay, bagaimana inisialisasi DirectPlay untuk model peer-to-peer pada bab selesai teman juga telah mengetahui bagaimana mengatur deksripsi peer. Pada artikel berikutnya, kita akan membahas bagaimana mengelola sesi permainan mencakup membuat dan bergabung dengan sebuah sesi.
Di di bab pertama artikel ini, teman sudah memperoleh info ihwal konsep dasar DirectPlay, bagaimana inisialisasi DirectPlay untuk model peer-to-peer pada bab selesai teman juga telah mengetahui bagaimana mengatur deksripsi peer. Pada artikel berikutnya, kita akan membahas bagaimana mengelola sesi permainan mencakup membuat dan bergabung dengan sebuah sesi.
Sumber https://soymedia.blogspot.com/