update
This commit is contained in:
parent
6d37ab0468
commit
99d68b0ee7
@ -1,83 +1,82 @@
|
|||||||
import WebSocket from "ws";
|
import WebSocket from "ws"
|
||||||
import { EventEmitter } from "stream";
|
import { EventEmitter } from "stream"
|
||||||
import { MyServer } from "./MyServer";
|
import { MyServer } from "./MyServer"
|
||||||
import { getTime, buffer2ArrayBuffer } from "../Utils";
|
import { getTime, buffer2ArrayBuffer } from "../Utils"
|
||||||
import { ApiMsgEnum, IModel } from "../Common";
|
import { ApiMsgEnum, IModel } from "../Common"
|
||||||
import { binaryEncode, binaryDecode } from "../Common/Binary";
|
import { binaryEncode, binaryDecode } from "../Common/Binary"
|
||||||
|
|
||||||
export enum ConnectionEventEnum {
|
export enum ConnectionEventEnum {
|
||||||
Close = "Close",
|
Close = "Close",
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IItem {
|
interface IItem {
|
||||||
cb: Function;
|
cb: Function
|
||||||
ctx: unknown;
|
ctx: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Connection extends EventEmitter {
|
export class Connection extends EventEmitter {
|
||||||
server: MyServer;
|
server: MyServer
|
||||||
ws: WebSocket;
|
ws: WebSocket
|
||||||
msgMap: Map<ApiMsgEnum, Array<IItem>> = new Map();
|
msgMap: Map<ApiMsgEnum, Array<IItem>> = new Map()
|
||||||
playerId?: number;
|
|
||||||
|
|
||||||
constructor(server: MyServer, ws: WebSocket) {
|
constructor(server: MyServer, ws: WebSocket) {
|
||||||
super();
|
super()
|
||||||
|
|
||||||
this.server = server;
|
this.server = server
|
||||||
this.ws = ws;
|
this.ws = ws
|
||||||
this.ws.on("close", (code: number, reason: Buffer) => {
|
this.ws.on("close", (code: number, reason: Buffer) => {
|
||||||
this.emit(ConnectionEventEnum.Close, code, reason.toString());
|
this.emit(ConnectionEventEnum.Close, code, reason.toString())
|
||||||
});
|
})
|
||||||
|
|
||||||
this.ws.on("message", (buffer: Buffer) => {
|
this.ws.on("message", (buffer: Buffer) => {
|
||||||
// const str = buffer.toString()
|
// const str = buffer.toString()
|
||||||
try {
|
try {
|
||||||
const json = binaryDecode(buffer2ArrayBuffer(buffer));
|
const json = binaryDecode(buffer2ArrayBuffer(buffer))
|
||||||
const { name, data } = json;
|
const { name, data } = json
|
||||||
// console.log(`${getTime()}接收|字节数${buffer.length}|${this.playerId || -1}|${str}`)
|
// console.log(`${getTime()}接收|字节数${buffer.length}|${this.playerId || -1}|${str}`)
|
||||||
console.log(`${getTime()}接收|字节数${buffer.length}|${this.playerId || -1}|${JSON.stringify(json)}`);
|
console.log(`${getTime()}接收|字节数${buffer.length}|${this.playerId || -1}|${JSON.stringify(json)}`)
|
||||||
if (this.server.apiMap.has(name)) {
|
if (this.server.apiMap.has(name)) {
|
||||||
try {
|
try {
|
||||||
const cb = this.server.apiMap.get(name);
|
const cb = this.server.apiMap.get(name)
|
||||||
const res = cb.call(null, this, data);
|
const res = cb.call(null, this, data)
|
||||||
this.sendMsg(name, {
|
this.sendMsg(name, {
|
||||||
success: true,
|
success: true,
|
||||||
res,
|
res,
|
||||||
});
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.sendMsg(name, {
|
this.sendMsg(name, {
|
||||||
success: false,
|
success: false,
|
||||||
error: (error as Error)?.message,
|
error: (error as Error)?.message,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (this.msgMap.has(name)) {
|
if (this.msgMap.has(name)) {
|
||||||
this.msgMap.get(name).forEach(({ cb, ctx }) => cb.call(ctx, this, data));
|
this.msgMap.get(name).forEach(({ cb, ctx }) => cb.call(ctx, this, data))
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`解析失败,不是合法的JSON格式:`, error);
|
console.log(`解析失败,不是合法的JSON格式:`, error)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
listenMsg<T extends keyof IModel["msg"]>(name: T, cb: (connection: Connection, arg: IModel["msg"][T]) => void, ctx: unknown) {
|
listenMsg<T extends keyof IModel["msg"]>(name: T, cb: (connection: Connection, arg: IModel["msg"][T]) => void, ctx: unknown) {
|
||||||
if (this.msgMap.has(name)) {
|
if (this.msgMap.has(name)) {
|
||||||
this.msgMap.get(name).push({ cb, ctx });
|
this.msgMap.get(name).push({ cb, ctx })
|
||||||
} else {
|
} else {
|
||||||
this.msgMap.set(name, [{ cb, ctx }]);
|
this.msgMap.set(name, [{ cb, ctx }])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlistenMsg<T extends keyof IModel["msg"]>(name: T, cb: (connection: Connection, arg: IModel["msg"][T]) => void, ctx: unknown) {
|
unlistenMsg<T extends keyof IModel["msg"]>(name: T, cb: (connection: Connection, arg: IModel["msg"][T]) => void, ctx: unknown) {
|
||||||
if (this.msgMap.has(name)) {
|
if (this.msgMap.has(name)) {
|
||||||
const items = this.msgMap.get(name);
|
const items = this.msgMap.get(name)
|
||||||
const index = items.findIndex((i) => cb === i.cb && i.ctx === ctx);
|
const index = items.findIndex((i) => cb === i.cb && i.ctx === ctx)
|
||||||
index > -1 && items.splice(index, 1);
|
index > -1 && items.splice(index, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,14 +84,14 @@ export class Connection extends EventEmitter {
|
|||||||
const msg = JSON.stringify({
|
const msg = JSON.stringify({
|
||||||
name,
|
name,
|
||||||
data,
|
data,
|
||||||
});
|
})
|
||||||
const view = binaryEncode(name, data);
|
const view = binaryEncode(name, data)
|
||||||
const buffer = Buffer.from(view.buffer);
|
const buffer = Buffer.from(view.buffer)
|
||||||
console.log(
|
console.log(
|
||||||
`${getTime()}发送|字节数${buffer.length}|${this.playerId || -1}|内存${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(
|
`${getTime()}发送|字节数${buffer.length}|${this.playerId || -1}|内存${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(
|
||||||
2
|
2
|
||||||
)}MB|${msg}`
|
)}MB|${msg}`
|
||||||
);
|
)
|
||||||
this.ws.send(buffer);
|
this.ws.send(buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Connection, MyServer, MyServerEventEnum } from "./Core";
|
import { Connection, MyServer, MyServerEventEnum } from "./Core"
|
||||||
import PlayerManager from "./Biz/PlayerManager";
|
import PlayerManager from "./Biz/PlayerManager"
|
||||||
import RoomManager from "./Biz/RoomManager";
|
import RoomManager from "./Biz/RoomManager"
|
||||||
import { getTime, symlinkCommon } from "./Utils";
|
import { getTime, symlinkCommon } from "./Utils"
|
||||||
import {
|
import {
|
||||||
ApiMsgEnum,
|
ApiMsgEnum,
|
||||||
IApiGameEndReq,
|
IApiGameEndReq,
|
||||||
@ -21,145 +21,151 @@ import {
|
|||||||
IApiRoomListReq,
|
IApiRoomListReq,
|
||||||
IApiRoomListRes,
|
IApiRoomListRes,
|
||||||
IModel,
|
IModel,
|
||||||
} from "./Common";
|
} from "./Common"
|
||||||
|
|
||||||
const server = new MyServer({ port: 8888 });
|
declare module "./Core" {
|
||||||
|
interface Connection {
|
||||||
|
playerId?: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = new MyServer({ port: 8888 })
|
||||||
|
|
||||||
// event
|
// event
|
||||||
server.on(MyServerEventEnum.Connect, (connection: Connection) => {
|
server.on(MyServerEventEnum.Connect, (connection: Connection) => {
|
||||||
console.log(`${getTime()}来人|人数|${server.connections.size}`);
|
console.log(`${getTime()}来人|人数|${server.connections.size}`)
|
||||||
});
|
})
|
||||||
|
|
||||||
server.on(MyServerEventEnum.DisConnect, (connection: Connection) => {
|
server.on(MyServerEventEnum.DisConnect, (connection: Connection) => {
|
||||||
console.log(`${getTime()}走人|人数|${server.connections.size}`);
|
console.log(`${getTime()}走人|人数|${server.connections.size}`)
|
||||||
if (connection.playerId) {
|
if (connection.playerId) {
|
||||||
PlayerManager.Instance.removePlayer(connection.playerId);
|
PlayerManager.Instance.removePlayer(connection.playerId)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
// api
|
// api
|
||||||
server.setApi(ApiMsgEnum.ApiPlayerList, (connection: Connection, data: IApiPlayerListReq): IApiPlayerListRes => {
|
server.setApi(ApiMsgEnum.ApiPlayerList, (connection: Connection, data: IApiPlayerListReq): IApiPlayerListRes => {
|
||||||
return { list: PlayerManager.Instance.getPlayersView() };
|
return { list: PlayerManager.Instance.getPlayersView() }
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiPlayerJoin, (connection: Connection, { nickname }: IApiPlayerJoinReq): IApiPlayerJoinRes => {
|
server.setApi(ApiMsgEnum.ApiPlayerJoin, (connection: Connection, { nickname }: IApiPlayerJoinReq): IApiPlayerJoinRes => {
|
||||||
const player = PlayerManager.Instance.createPlayer({ connection, nickname });
|
const player = PlayerManager.Instance.createPlayer({ connection, nickname })
|
||||||
PlayerManager.Instance.syncPlayers();
|
PlayerManager.Instance.syncPlayers()
|
||||||
return {
|
return {
|
||||||
player: PlayerManager.Instance.getPlayerView(player),
|
player: PlayerManager.Instance.getPlayerView(player),
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiRoomList, (connection: Connection, data: IApiRoomListReq): IApiRoomListRes => {
|
server.setApi(ApiMsgEnum.ApiRoomList, (connection: Connection, data: IApiRoomListReq): IApiRoomListRes => {
|
||||||
return { list: RoomManager.Instance.getRoomsView() };
|
return { list: RoomManager.Instance.getRoomsView() }
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiRoomCreate, (connection: Connection, data: IApiRoomCreateReq): IApiRoomCreateRes => {
|
server.setApi(ApiMsgEnum.ApiRoomCreate, (connection: Connection, data: IApiRoomCreateReq): IApiRoomCreateRes => {
|
||||||
if (connection.playerId) {
|
if (connection.playerId) {
|
||||||
const room = RoomManager.Instance.joinRoom(RoomManager.Instance.createRoom().id, connection.playerId);
|
const room = RoomManager.Instance.joinRoom(RoomManager.Instance.createRoom().id, connection.playerId)
|
||||||
if (room) {
|
if (room) {
|
||||||
RoomManager.Instance.syncRooms();
|
RoomManager.Instance.syncRooms()
|
||||||
PlayerManager.Instance.syncPlayers();
|
PlayerManager.Instance.syncPlayers()
|
||||||
return {
|
return {
|
||||||
room: RoomManager.Instance.getRoomView(room),
|
room: RoomManager.Instance.getRoomView(room),
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomCreate room不存在");
|
throw new Error("ApiRoomCreate room不存在")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomCreate 玩家未登录");
|
throw new Error("ApiRoomCreate 玩家未登录")
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiRoomJoin, (connection: Connection, data: IApiRoomJoinReq): IApiRoomJoinRes => {
|
server.setApi(ApiMsgEnum.ApiRoomJoin, (connection: Connection, data: IApiRoomJoinReq): IApiRoomJoinRes => {
|
||||||
if (connection.playerId) {
|
if (connection.playerId) {
|
||||||
const room = RoomManager.Instance.joinRoom(data.rid, connection.playerId);
|
const room = RoomManager.Instance.joinRoom(data.rid, connection.playerId)
|
||||||
if (room) {
|
if (room) {
|
||||||
RoomManager.Instance.syncRooms();
|
RoomManager.Instance.syncRooms()
|
||||||
PlayerManager.Instance.syncPlayers();
|
PlayerManager.Instance.syncPlayers()
|
||||||
RoomManager.Instance.syncRoom(room.id);
|
RoomManager.Instance.syncRoom(room.id)
|
||||||
return {
|
return {
|
||||||
room: RoomManager.Instance.getRoomView(room),
|
room: RoomManager.Instance.getRoomView(room),
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomJoin room不存在");
|
throw new Error("ApiRoomJoin room不存在")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomJoin 玩家未登录");
|
throw new Error("ApiRoomJoin 玩家未登录")
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiRoomLeave, (connection: Connection, data: IApiRoomLeaveReq): IApiRoomLeaveRes => {
|
server.setApi(ApiMsgEnum.ApiRoomLeave, (connection: Connection, data: IApiRoomLeaveReq): IApiRoomLeaveRes => {
|
||||||
if (connection.playerId) {
|
if (connection.playerId) {
|
||||||
const player = PlayerManager.Instance.getPlayerById(connection.playerId);
|
const player = PlayerManager.Instance.getPlayerById(connection.playerId)
|
||||||
if (player) {
|
if (player) {
|
||||||
const rid = player.rid;
|
const rid = player.rid
|
||||||
if (rid) {
|
if (rid) {
|
||||||
RoomManager.Instance.leaveRoom(rid, player.id);
|
RoomManager.Instance.leaveRoom(rid, player.id)
|
||||||
PlayerManager.Instance.syncPlayers();
|
PlayerManager.Instance.syncPlayers()
|
||||||
RoomManager.Instance.syncRooms();
|
RoomManager.Instance.syncRooms()
|
||||||
RoomManager.Instance.syncRoom(rid);
|
RoomManager.Instance.syncRoom(rid)
|
||||||
return {};
|
return {}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomLeave 玩家不在房间");
|
throw new Error("ApiRoomLeave 玩家不在房间")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomLeave 玩家不存在");
|
throw new Error("ApiRoomLeave 玩家不存在")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomLeave 玩家未登录");
|
throw new Error("ApiRoomLeave 玩家未登录")
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiGameStart, (connection: Connection, data: IApiGameStartReq): IApiGameStartRes => {
|
server.setApi(ApiMsgEnum.ApiGameStart, (connection: Connection, data: IApiGameStartReq): IApiGameStartRes => {
|
||||||
if (connection.playerId) {
|
if (connection.playerId) {
|
||||||
const player = PlayerManager.Instance.getPlayerById(connection.playerId);
|
const player = PlayerManager.Instance.getPlayerById(connection.playerId)
|
||||||
if (player) {
|
if (player) {
|
||||||
const rid = player.rid;
|
const rid = player.rid
|
||||||
if (rid) {
|
if (rid) {
|
||||||
RoomManager.Instance.startRoom(rid);
|
RoomManager.Instance.startRoom(rid)
|
||||||
PlayerManager.Instance.syncPlayers();
|
PlayerManager.Instance.syncPlayers()
|
||||||
RoomManager.Instance.syncRooms();
|
RoomManager.Instance.syncRooms()
|
||||||
return {};
|
return {}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomLeave 玩家不在房间");
|
throw new Error("ApiRoomLeave 玩家不在房间")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomLeave 玩家不存在");
|
throw new Error("ApiRoomLeave 玩家不存在")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiRoomLeave 玩家未登录");
|
throw new Error("ApiRoomLeave 玩家未登录")
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
server.setApi(ApiMsgEnum.ApiGameEnd, (connection: Connection, data: IApiGameEndReq): IApiGameEndRes => {
|
server.setApi(ApiMsgEnum.ApiGameEnd, (connection: Connection, data: IApiGameEndReq): IApiGameEndRes => {
|
||||||
if (connection.playerId) {
|
if (connection.playerId) {
|
||||||
const player = PlayerManager.Instance.getPlayerById(connection.playerId);
|
const player = PlayerManager.Instance.getPlayerById(connection.playerId)
|
||||||
if (player) {
|
if (player) {
|
||||||
const rid = player.rid;
|
const rid = player.rid
|
||||||
if (rid) {
|
if (rid) {
|
||||||
RoomManager.Instance.closeRoom(rid);
|
RoomManager.Instance.closeRoom(rid)
|
||||||
PlayerManager.Instance.syncPlayers();
|
PlayerManager.Instance.syncPlayers()
|
||||||
RoomManager.Instance.syncRooms();
|
RoomManager.Instance.syncRooms()
|
||||||
return {};
|
return {}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiGameEnd 玩家不在房间");
|
throw new Error("ApiGameEnd 玩家不在房间")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiGameEnd 玩家不存在");
|
throw new Error("ApiGameEnd 玩家不存在")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("ApiGameEnd 玩家未登录");
|
throw new Error("ApiGameEnd 玩家未登录")
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
// start!!
|
// start!!
|
||||||
server
|
server
|
||||||
.start()
|
.start()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
symlinkCommon();
|
symlinkCommon()
|
||||||
console.log("服务启动!");
|
console.log("服务启动!")
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log("服务异常", e);
|
console.log("服务异常", e)
|
||||||
});
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user