بدأ العديد من المطورين في تطوير خادم متعدد المستخدمين عبر الإنترنت استنادًا إلى مكتبة socket.io . تجعل هذه المكتبة من السهل جدًا تنفيذ تبادل البيانات بين العميل والخادم في الوقت الفعلي ، ولكن لا يزال يتعين عليك التفكير في كل منطق وواجهة التفاعل بين الخادم والعميل ، بالإضافة إلى بنية القياس وتحسين حركة المرور.
أريد أن أتحدث عن مكتبة magx ، والتي باستخدامها لا يمكنك التفكير في مكون الشبكة (الاتصال بين الخادم والعملاء) ، ولكن التركيز فورًا على تطوير منطق اللعبة وواجهة المستخدم للعميل.
عند تصميم بنية لعبة متعددة اللاعبين ، عادة ما يتم أخذ طريقتين في الاعتبار: مع خادم استبدادي وغير سلطوي (عميل سلطوي). يتم دعم كل من هذه الأساليب بواسطة مكتبة magx. لنبدأ بنهج أبسط - غير سلطوي.
خادم غير موثوق
جوهرها هو أن الخادم لا يتحكم في نتائج الإدخال لكل لاعب. يتتبع العملاء بشكل مستقل الإجراءات التي أدخلها اللاعب ومنطق اللعبة محليًا ، وبعد ذلك يرسلون نتيجة إجراء معين إلى الخادم. بعد ذلك ، يقوم الخادم بمزامنة جميع الإجراءات التي تم تنفيذها مع حالة اللعبة للعملاء الآخرين.
من الأسهل التنفيذ من وجهة نظر معمارية ، لأن الخادم مسؤول فقط عن الاتصال بين العملاء ، دون إجراء أي حسابات إضافية يقوم بها العملاء.
باستخدام مكتبة magx ، يمكن تنفيذ مثل هذا الخادم في بضعة أسطر من التعليمات البرمجية:
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}`)
})
الآن ، لتوصيل العملاء بهذا الخادم وبدء تفاعلهم ، ما عليك سوى تثبيت مكتبة js:
npm install --save magx-client
وربطه بالمشروع:
import { Client } from "magx-client"
بدلاً من ذلك ، يمكنك استخدام رابط مباشر لاستخدام HTML:
<script src="https://cdn.jsdelivr.net/npm/magx-client@0.7.1/dist/magx.js"></script>
بعد الاتصال ، ستتيح لك بضعة أسطر فقط تكوين الاتصال والتفاعل مع الخادم:
// 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))
تم وصف مثال مفصل لكيفية بناء تفاعل بين العملاء وخادم غير موثوق في المثال المقابل في مشروع magx -amples .
خادم موثوق
, , - .
- . , , , , .
, . , (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)
- ( )
- ( )
- ( )
- الغرف المدمجة: اللوبي والتتابع (للخادم غير المعتمد)
- مكتبة JS Magx-client للعمل مع الخادم
- مراقبة وحدة التحكم magx-Monitor لإدارة غرف الخادم وعملائها وحالة المشاهدة
- دعم كامل للطباعة
- الحد الأدنى من التبعيات (لمكتبة notepack.io - لتقليل حركة مرور الشبكة)
هذا المشروع صغير جدًا وآمل أن يساعده اهتمام المجتمع في تطويره بشكل أسرع.