Banyak pengembang mulai mengembangkan server online multipengguna berdasarkan pustaka socket.io . Pustaka ini membuatnya sangat mudah untuk mengimplementasikan pertukaran data antara klien dan server secara real time, tetapi Anda masih harus memikirkan dan mengimplementasikan semua logika dan antarmuka interaksi server-klien, serta arsitektur untuk penskalaan dan pengoptimalan lalu lintas.
Saya ingin berbicara tentang pustaka magx , yang dengannya Anda tidak dapat memikirkan komponen jaringan (komunikasi antara server dan klien), tetapi segera berkonsentrasi pada pengembangan logika permainan dan UI klien.
Saat mengembangkan arsitektur game multipemain, 2 pendekatan biasanya dipertimbangkan: dengan server otoriter dan non-otoriter (klien otoriter). Kedua pendekatan ini didukung oleh perpustakaan magx. Mari kita mulai dengan pendekatan yang lebih sederhana - non-otoriter.
Server non-otoritatif
Intinya adalah server tidak mengontrol hasil input setiap pemain. Klien secara independen melacak tindakan yang dimasukkan oleh pemain dan logika permainan secara lokal, setelah itu mereka mengirimkan hasil dari tindakan tertentu ke server. Setelah itu, server menyinkronkan semua tindakan yang dilakukan dengan status game klien lain.
Lebih mudah untuk mengimplementasikan dari sudut pandang arsitektural, karena server hanya bertanggung jawab untuk komunikasi antar klien, tanpa melakukan kalkulasi tambahan yang dilakukan klien.
Menggunakan pustaka magx, server seperti itu dapat diimplementasikan hanya dalam beberapa baris kode:
import * as http from "http"
import { Server, RelayRoom } from "magx"
const server = http.createServer()
const magx = new Server(server)
magx.define("relay", RelayRoom)
// start server
const port = process.env.PORT || 3001
server.listen(port, () => {
console.info(`Server started on http://localhost:${port}`)
})
Sekarang, untuk menghubungkan klien ke server ini dan memulai interaksi mereka, cukup instal js library:
npm install --save magx-client
dan hubungkan ke proyek:
import { Client } from "magx-client"
Atau, Anda dapat menggunakan tautan langsung untuk penggunaan HTML:
<script src="https://cdn.jsdelivr.net/npm/magx-client@0.7.1/dist/magx.js"></script>
Setelah terhubung, hanya dengan beberapa baris Anda dapat mengonfigurasi koneksi dan interaksi dengan server:
// authenticate to server
await client.authenticate()
// create or join room
const rooms = await client.getRooms("relay")
room = rooms.length
? await client.joinRoom(rooms[0].id)
: await client.createRoom("relay")
console.log("you joined room", name)
// handle state patches
room.onPatch((patch) => updateState(patch))
// handle state snapshot
room.onSnapshot((snapshot) => setState(snapshot))
// handle joined players
room.onMessage("player_join", (id) => console.log("player join", id))
// handle left players
room.onMessage("player_leave", (id) => console.log("player leave", id))
Contoh mendetail tentang cara membangun interaksi antara klien dan server non-otoritatif dijelaskan dalam contoh terkait di proyek contoh-magx .
Server resmi
, , - .
- . , , , , .
, . , (cheating).
. magx , (worker). , .
/ . — . Mosx — , magx - , .
, . mosx — @mx.Object, , @mx. :
@mx.Object
export class Player {
@mx public x = Math.floor(Math.random() * 400)
@mx public y = Math.floor(Math.random() * 400)
}
@mx.Object
export class State {
@mx public players = new Map<string, Player>()
public createPlayer(id: string) {
this.players.set(id, new Player())
}
public removePlayer(id: string) {
this.players.delete(id)
}
public movePlayer(id: string, movement: any) {
const player = this.players.get(id)
if (!player) { return }
player.x += movement.x ? movement.x * 10 : 0
player.y += movement.y ? movement.y * 10 : 0
}
}
, — Map() . (Array) (number, string, boolean) .
. :
export class MosxStateRoom extends Room<State> {
public createState(): any {
// create state
return new State()
}
public createPatchTracker(state: State) {
// create state change tracker
return Mosx.createTracker(state)
}
public onCreate(params: any) {
console.log("MosxStateRoom created!", params)
}
public onMessage(client: Client, type: string, data: any) {
if (type === "move") {
console.log(`MosxStateRoom received message from ${client.id}`, data)
this.state.movePlayer(client.id, data)
}
}
public onJoin(client: Client, params: any) {
console.log(`Player ${client.id} joined MosxStateRoom`, params)
client.send("hello", "world")
this.state.createPlayer(client.id)
}
public onLeave(client: Client) {
this.state.removePlayer(client.id)
}
public onClose() {
console.log("MosxStateRoom closed!")
}
}
— .
const magx = new Server(server, params)
magx.define("mosx-state", MosxStateRoom)
?
:
Mosx
Magx
- API.
- :
- ( webockets)
- ( )
- ( )
- ( )
- Kamar built-in: lobi dan relai (untuk server non-otoritatif)
- Pustaka klien JS Magx untuk bekerja dengan server
- Konsol pemantauan magx-monitor untuk mengelola ruang server, klien mereka, dan status tampilan
- Dukungan Typecript penuh
- Dependensi minimum (untuk pustaka notepack.io - untuk mengurangi lalu lintas jaringan)
Proyek ini masih cukup muda dan saya berharap perhatian dari komunitas akan membantunya berkembang lebih cepat.