Bahasa: C++ dengan lem logika Lua.
Kode telah diuji untuk dikompilasi dan dijalankan pada Ubuntu x86, Ubuntu x86_64 dan Gentoo x86_64 mengingat versi LuaJIT yang tepat digunakan. Modifikasi pada libjansson untuk menghapus pemformatan paksa float dengan .0 setelah bilangan bulat dilakukan untuk mendukung "integer" dengan benar dan masih memiliki konversi otomatis dari Lua, yang hanya mendukung ganda.
Itu juga dikompilasi di Ubuntu 12.04 LTS x86_64, mengingat libjansson dan google-glog dibuat secara manual.
LuaJIT
gratis
acarahttpclient
google-glog
google-perftools (tcmalloc) - Opsional dengan sedikit modifikasi sumber dan makefile
libjansson
disewa
libicu - lihat manajer paket lokal
curl - lihat manajer paket lokal
boost - Opsional jika Anda mengganti petunjuk yang mengganggu dengan sesuatu milik Anda sendiri.
Modifikasi pada src/Makefile untuk mencerminkan folder instalasi Anda mungkin diperlukan. Sistem pembangunan yang lebih kuat disambut baik, tetapi tidak diperlukan pada saat proyek ini ditulis. (CMembuat?)
Saya (@zwagoth) belajar sesuatu di sini: Selalu memberi komentar pada saat menulis. Untuk mengatasinya saya akan mendokumentasikan struktur dasar program untuk membantu pemahaman.
Permintaan maaf atas kekacauan basis kode. Ini juga merupakan salah satu proyek C++ pertama saya dengan skala dan kompleksitas apa pun.
Berisi hampir semua logika inti untuk penanganan pesan pesan protokol, pesan RTB, dan berbagai callback kejadian dasar seperti koneksi dan pemutusan.
File tersebut berisi tabel fungsi anonim yang diberi nama berdasarkan peristiwa yang ditanganinya. File ini tidak boleh menyimpan status apa pun dan dianggap sebagai tempat penyimpanan logika saja. Desain dasar dari file ini adalah untuk memungkinkan logika lem tanpa memaksa Lua melakukan pekerjaan berat dan meminimalkan jumlah data yang ditransfer masuk dan keluar dari Lua dengan mengorbankan lebih banyak pemanggilan fungsi ke dalam C++.
Ada empat tabel yang dimasukkan ke dalam namespace file global dengan nama pendek untuk kemudahan pengetikan:
u
: fungsi koneksi/karakter(pengguna).
s
: fungsi server/negara global
c
: fungsi status saluran
const
: id kesalahan dan nilai konstan
Fungsi panggilan balik protokol menerima dua parameter, koneksi yang dikaitkan dengan perintah, dan salinan tabel argumen json yang disediakan.
Koneksi adalah nomor buram dan TIDAK boleh diubah dengan cara apa pun. Mengubah nilai koneksi tidak aman. Anda telah diperingatkan.
File lua dari variabel konfigurasi yang digunakan selama permulaan dan pengoperasian daemon obrolan.
Server kebijakan flash minimalis. Jika Anda perlu mendukung Flash, inilah yang Anda jalankan. Sesuaikan kebijakan yang tercantum dengan kebutuhan Anda.
Titik masuk program. Berurusan dengan inisialisasi thread latar belakang dan curl.
Melakukan terlalu banyak hal. Alur kode dimulai di Server::run()
.
Alur koneksi adalah sebagai berikut:
listenCallback handshakeCallback connectionWriteCallback connectionReadCallback connectionwriteCallback
listenCallback
menyiapkan per pengendali peristiwa koneksi dan meneruskan aliran ke...
handshakeCallback
, yang menangani pembacaan jabat tangan websocket.
connectionWriteCallback
menangani ketika koneksi siap untuk ditulis dan diaktifkan ketika item berada dalam antrian untuk ditulis ke koneksi. Menangani buffering.
connectionReadCallback
menangani semua peristiwa baca ketika fase jabat tangan selesai. Semua penguraian protokol terjadi di sini dan perintah dikirim dan dijalankan dari dalam fungsi ini.
pingCallback
menangani pengiriman acara ping ke klien. Jika protokolnya diubah, ini harus menjadi salah satu hal pertama yang harus dilakukan.
connectionTimerCallback
diaktifkan secara berkala dan memeriksa apakah koneksi mati dan membersihkannya.
runLuaEvent
adalah keajaiban baru. Juga di mana keajaiban terjadi untuk setiap perintah. Di sinilah setiap perintah beralih ke kode Lua dari kode C++. Menangani semua status Lua dan callback untuk memastikan Lua tidak terjebak dalam perulangan tak terbatas. Menangani kesalahan pencetakan dari dalam Lua.
File ini menyimpan semua data negara terkait saluran, koneksi, larangan, dan moderasi.
Koneksi dibagi antara teridentifikasi dan tidak teridentifikasi karena nama karakter tidak diketahui hingga server login memvalidasi keberadaannya dan untuk menjauhkannya dari kumpulan karakter yang dapat dicari berdasarkan namanya.
Menangani penyimpanan dan pemulihan status ke disk.
Berjalan sebagai thread latar belakang yang memproses permintaan login dan balasan serta meneruskannya kembali ke thread utama.
Sistem login berseri, menggunakan antrian login global. Hal ini dapat ditingkatkan sedikit.
Konversi ke curl_multi akan menyenangkan, tetapi melibatkan interaksi yang menyenangkan dengan libev atau banyak polling buta. Antrian harus dikunci sebelum diakses, karena threading.
Kelas saluran dasar, memelihara data status tentang suatu saluran selama masa pakainya. Semua tindakan tingkat rendah yang berhubungan dengan saluran terjadi dalam file ini melalui hook di Lua. Biasanya dibungkus dengan pointer yang mengganggu untuk mengelola masa pakai instance.
Di sinilah serialisasi dan deserialisasi saluran dari json terjadi.
Menangani semua jaringan koneksi dan men-debug status Lua.
Mempertahankan daftar ketegaran, status, pesan status dan jenis kelamin.
Mempertahankan abaikan dan daftar teman.
Menangani per sambungan throttle.
Di sinilah terjadi buffering data keluaran.
Umumnya diedarkan menggunakan petunjuk intrusif untuk mengelola masa pakai instance.
Mempertahankan daftar internal saluran mana yang telah bergabung. Ini harus tetap sinkron dengan daftar pengguna saluran yang sebenarnya.
File ini dicadangkan untuk beberapa fungsi yang memerlukan kecepatan mentah agar dapat disesuaikan. Menangani perintah login ( IDN
). Menangani perintah debug ( ZZZ
). Menangani perintah pencarian ( FKS
).
Semua perintah pembungkus Lua yang masuk dalam kategori s
dalam berkas Lua.
Semua perintah pembungkus Lua yang termasuk dalam kategori u
dalam berkas Lua.
Semua perintah pembungkus Lua yang masuk dalam kategori c
dalam berkas Lua.
Semua nilai pembungkus Lua yang termasuk dalam kategori const
dalam berkas Lua.
Pesan kesalahan dan definisi.
Gunakan makro yang ditentukan untuk pemeriksaan kesalahan dan pengetikan! Ini adalah satu-satunya cara untuk mencegah error jika tipe yang salah diteruskan sebagai data ringan ke suatu fungsi secara tidak terduga.
Pastikan tumpukan Lua Anda seimbang. Saya telah berusaha keras untuk memastikan hal ini benar, namun kesalahan mudah dilakukan.
Hindari mengembalikan tabel ke kode Lua, karena pembuatannya mahal dan sering kali memiliki jangka waktu penggunaan yang singkat. Gunakan penilaian terbaik untuk menyeimbangkan biaya pemanggilan fungsi dan biaya pembuatan tabel.
Hindari meneruskan string ke Lua dengan sia-sia. Ini bisa mahal karena salinan memori.
Penyalahgunaan bahwa lua menerima beberapa nilai kembalian sebagai fitur asli. Lihat dua catatan di atas.
Menangani thread redis hanya dorong. Adalah pembungkus kecil di sekitar perintah redis dan nilai kembaliannya.
Menggunakan antrian input untuk menerima perintah. Perintah dijalankan secara berkala dan tidak memiliki jaminan keandalan. Dapat dinonaktifkan, dan mengabaikan input saat dinonaktifkan.
gdb berfungsi dengan baik untuk men-debug aplikasi ini. Menonaktifkan tcmalloc dan bagian JIT dari LuaJIT akan sangat membantu dalam debugging crash (tcmalloc dapat menyembunyikan beberapa kerusakan heap kecil).
Alat pembuatan profil memori di tcmalloc cukup bagus. Lihat dokumentasi tcmalloc untuk informasi lebih lanjut tentang cara menggunakannya.