FEATURE: the connexion error an user can get when a world is full is now correctly traited. Also remove a redundant adminApi call
This commit is contained in:
parent
ad7e16c33b
commit
8abc34c631
11 changed files with 127 additions and 215 deletions
|
@ -1,5 +1,5 @@
|
|||
import {CharacterLayer, ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
|
||||
import {GameRoomPolicyTypes} from "../Model/PusherRoom";
|
||||
import {GameRoomPolicyTypes, PusherRoom} from "../Model/PusherRoom";
|
||||
import {PointInterface} from "../Model/Websocket/PointInterface";
|
||||
import {
|
||||
SetPlayerDetailsMessage,
|
||||
|
@ -20,7 +20,7 @@ import {parse} from "query-string";
|
|||
import {jwtTokenManager} from "../Services/JWTTokenManager";
|
||||
import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "../Services/AdminApi";
|
||||
import {SocketManager, socketManager} from "../Services/SocketManager";
|
||||
import {emitInBatch} from "../Services/IoSocketHelpers";
|
||||
import {emitError, emitInBatch} from "../Services/IoSocketHelpers";
|
||||
import {ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER} from "../Enum/EnvironmentVariable";
|
||||
import {Zone} from "_Model/Zone";
|
||||
import {ExAdminSocketInterface} from "_Model/Websocket/ExAdminSocketInterface";
|
||||
|
@ -108,7 +108,6 @@ export class IoSocketController {
|
|||
maxBackpressure: 65536, // Maximum 64kB of data in the buffer.
|
||||
//idleTimeout: 10,
|
||||
upgrade: (res, req, context) => {
|
||||
//console.log('An Http connection wants to become WebSocket, URL: ' + req.getUrl() + '!');
|
||||
(async () => {
|
||||
/* Keep track of abortions */
|
||||
const upgradeAborted = {aborted: false};
|
||||
|
@ -156,12 +155,9 @@ export class IoSocketController {
|
|||
const userUuid = await jwtTokenManager.getUserUuidFromToken(token, IPAddress, roomId);
|
||||
|
||||
let memberTags: string[] = [];
|
||||
let memberMessages: unknown;
|
||||
let memberTextures: CharacterTexture[] = [];
|
||||
const room = await socketManager.getOrCreateRoom(roomId);
|
||||
// TODO: make sure the room isFull is ported in the back part.
|
||||
/*if(room.isFull){
|
||||
throw new Error('Room is full');
|
||||
}*/
|
||||
if (ADMIN_API_URL) {
|
||||
try {
|
||||
let userData : FetchMemberDataByUuidResponse = {
|
||||
|
@ -172,15 +168,26 @@ export class IoSocketController {
|
|||
anonymous: true
|
||||
};
|
||||
try {
|
||||
userData = await adminApi.fetchMemberDataByUuid(userUuid);
|
||||
userData = await adminApi.fetchMemberDataByUuid(userUuid, roomId);
|
||||
}catch (err){
|
||||
if (err?.response?.status == 404) {
|
||||
// If we get an HTTP 404, the token is invalid. Let's perform an anonymous login!
|
||||
console.warn('Cannot find user with uuid "'+userUuid+'". Performing an anonymous login instead.');
|
||||
} else if(err?.response?.status == 403) {
|
||||
// If we get an HTTP 404, the world is full. We need to broadcast a special error to the client.
|
||||
// we finish immediatly the upgrade then we will close the socket as soon as it starts opening.
|
||||
res.upgrade({
|
||||
rejected: true,
|
||||
}, websocketKey,
|
||||
websocketProtocol,
|
||||
websocketExtensions,
|
||||
context);
|
||||
return;
|
||||
}else{
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
memberMessages = userData.messages;
|
||||
memberTags = userData.tags;
|
||||
memberTextures = userData.textures;
|
||||
if (!room.anonymous && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags))) {
|
||||
|
@ -215,6 +222,7 @@ export class IoSocketController {
|
|||
roomId,
|
||||
name,
|
||||
characterLayers: characterLayerObjs,
|
||||
messages: memberMessages,
|
||||
tags: memberTags,
|
||||
textures: memberTextures,
|
||||
position: {
|
||||
|
@ -241,7 +249,6 @@ export class IoSocketController {
|
|||
console.log(e.message);
|
||||
res.writeStatus("401 Unauthorized").end(e.message);
|
||||
} else {
|
||||
console.log(e);
|
||||
res.writeStatus("500 Internal Server Error").end('An error occurred');
|
||||
}
|
||||
return;
|
||||
|
@ -250,32 +257,30 @@ export class IoSocketController {
|
|||
},
|
||||
/* Handlers */
|
||||
open: (ws) => {
|
||||
if(ws.rejected === true) {
|
||||
emitError(ws, 'World is full');
|
||||
ws.close();
|
||||
}
|
||||
|
||||
// Let's join the room
|
||||
const client = this.initClient(ws); //todo: into the upgrade instead?
|
||||
socketManager.handleJoinRoom(client);
|
||||
|
||||
//get data information and show messages
|
||||
if (ADMIN_API_URL) {
|
||||
adminApi.fetchMemberDataByUuid(client.userUuid).then((res: FetchMemberDataByUuidResponse) => {
|
||||
if (!res.messages) {
|
||||
return;
|
||||
if (client.messages && Array.isArray(client.messages)) {
|
||||
client.messages.forEach((c: unknown) => {
|
||||
const messageToSend = c as { type: string, message: string };
|
||||
|
||||
const sendUserMessage = new SendUserMessage();
|
||||
sendUserMessage.setType(messageToSend.type);
|
||||
sendUserMessage.setMessage(messageToSend.message);
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
serverToClientMessage.setSendusermessage(sendUserMessage);
|
||||
|
||||
if (!client.disconnecting) {
|
||||
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
||||
}
|
||||
res.messages.forEach((c: unknown) => {
|
||||
const messageToSend = c as { type: string, message: string };
|
||||
|
||||
const sendUserMessage = new SendUserMessage();
|
||||
sendUserMessage.setType(messageToSend.type);
|
||||
sendUserMessage.setMessage(messageToSend.message);
|
||||
|
||||
const serverToClientMessage = new ServerToClientMessage();
|
||||
serverToClientMessage.setSendusermessage(sendUserMessage);
|
||||
|
||||
if (!client.disconnecting) {
|
||||
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
||||
}
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.error('fetchMemberDataByUuid => err', err);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -340,6 +345,7 @@ export class IoSocketController {
|
|||
}
|
||||
client.disconnecting = false;
|
||||
|
||||
client.messages = ws.messages;
|
||||
client.name = ws.name;
|
||||
client.tags = ws.tags;
|
||||
client.textures = ws.textures;
|
||||
|
|
|
@ -36,6 +36,7 @@ export interface ExSocketInterface extends WebSocket, Identificable {
|
|||
batchedMessages: BatchMessage;
|
||||
batchTimeout: NodeJS.Timeout|null;
|
||||
disconnecting: boolean,
|
||||
messages: unknown,
|
||||
tags: string[],
|
||||
textures: CharacterTexture[],
|
||||
backConnection: BackConnection,
|
||||
|
|
|
@ -58,12 +58,12 @@ class AdminApi {
|
|||
return res.data;
|
||||
}
|
||||
|
||||
async fetchMemberDataByUuid(uuid: string): Promise<FetchMemberDataByUuidResponse> {
|
||||
async fetchMemberDataByUuid(uuid: string, roomId: string): Promise<FetchMemberDataByUuidResponse> {
|
||||
if (!ADMIN_API_URL) {
|
||||
return Promise.reject('No admin backoffice set!');
|
||||
}
|
||||
const res = await Axios.get(ADMIN_API_URL+'/api/membership/'+uuid,
|
||||
{ headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
|
||||
const res = await Axios.get(ADMIN_API_URL+'/api/room/access',
|
||||
{ params: {uuid, roomId}, headers: {"Authorization" : `${ADMIN_API_TOKEN}`} }
|
||||
)
|
||||
return res.data;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {ExSocketInterface} from "_Model/Websocket/ExSocketInterface";
|
||||
import {BatchMessage, ErrorMessage, ServerToClientMessage, SubMessage} from "../Messages/generated/messages_pb";
|
||||
import {WebSocket} from "uWebSockets.js";
|
||||
|
||||
export function emitInBatch(socket: ExSocketInterface, payload: SubMessage): void {
|
||||
socket.batchedMessages.addPayload(payload);
|
||||
|
@ -20,7 +21,7 @@ export function emitInBatch(socket: ExSocketInterface, payload: SubMessage): voi
|
|||
}
|
||||
}
|
||||
|
||||
export function emitError(Client: ExSocketInterface, message: string): void {
|
||||
export function emitError(Client: WebSocket, message: string): void {
|
||||
const errorMessage = new ErrorMessage();
|
||||
errorMessage.setMessage(message);
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import {
|
|||
GroupDeleteMessage,
|
||||
ItemEventMessage,
|
||||
PlayGlobalMessage,
|
||||
PositionMessage,
|
||||
RoomJoinedMessage,
|
||||
ServerToClientMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
|
@ -25,21 +24,15 @@ import {
|
|||
SendUserMessage,
|
||||
BanUserMessage, UserJoinedRoomMessage, UserLeftRoomMessage
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import {PointInterface} from "../Model/Websocket/PointInterface";
|
||||
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
|
||||
import {cpuTracker} from "./CpuTracker";
|
||||
import {GROUP_RADIUS, JITSI_ISS, MINIMUM_DISTANCE, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
|
||||
import {Movable} from "../Model/Movable";
|
||||
import {PositionInterface} from "../Model/PositionInterface";
|
||||
import {JITSI_ISS, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
|
||||
import {adminApi, CharacterTexture} from "./AdminApi";
|
||||
import Direction = PositionMessage.Direction;
|
||||
import {emitError, emitInBatch} from "./IoSocketHelpers";
|
||||
import Jwt from "jsonwebtoken";
|
||||
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
||||
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
||||
import {gaugeManager} from "./GaugeManager";
|
||||
import {apiClientRepository} from "./ApiClientRepository";
|
||||
import {ServiceError} from "grpc";
|
||||
import {GroupDescriptor, UserDescriptor, ZoneEventListener} from "_Model/Zone";
|
||||
import Debug from "debug";
|
||||
import {ExAdminSocketInterface} from "_Model/Websocket/ExAdminSocketInterface";
|
||||
|
@ -408,17 +401,7 @@ export class SocketManager implements ZoneEventListener {
|
|||
//check and create new world for a room
|
||||
let world = this.Worlds.get(roomId)
|
||||
if(world === undefined){
|
||||
world = new PusherRoom(
|
||||
roomId,
|
||||
this
|
||||
/* (user: User, group: Group) => this.joinWebRtcRoom(user, group),
|
||||
(user: User, group: Group) => this.disConnectedUser(user, group),
|
||||
MINIMUM_DISTANCE,
|
||||
GROUP_RADIUS,
|
||||
(thing: Movable, listener: User) => this.onRoomEnter(thing, listener),
|
||||
(thing: Movable, position:PositionInterface, listener:User) => this.onClientMove(thing, position, listener),
|
||||
(thing: Movable, listener:User) => this.onClientLeave(thing, listener)*/
|
||||
);
|
||||
world = new PusherRoom(roomId, this);
|
||||
if (!world.anonymous) {
|
||||
const data = await adminApi.fetchMapDetails(world.organizationSlug, world.worldSlug, world.roomSlug)
|
||||
world.tags = data.tags
|
||||
|
@ -429,60 +412,6 @@ export class SocketManager implements ZoneEventListener {
|
|||
return Promise.resolve(world)
|
||||
}
|
||||
|
||||
/* private joinRoom(client : ExSocketInterface, position: PointInterface): PusherRoom {
|
||||
|
||||
const roomId = client.roomId;
|
||||
client.position = position;
|
||||
|
||||
const world = this.Worlds.get(roomId)
|
||||
if(world === undefined){
|
||||
throw new Error('Could not find room for ID: '+client.roomId)
|
||||
}
|
||||
|
||||
// Dispatch groups position to newly connected user
|
||||
world.getGroups().forEach((group: Group) => {
|
||||
this.emitCreateUpdateGroupEvent(client, group);
|
||||
});
|
||||
//join world
|
||||
world.join(client, client.position);
|
||||
clientEventsEmitter.emitClientJoin(client.userUuid, client.roomId);
|
||||
console.log(new Date().toISOString() + ' A user joined (', this.sockets.size, ' connected users)');
|
||||
return world;
|
||||
}
|
||||
|
||||
private onClientMove(thing: Movable, position:PositionInterface, listener:User): void {
|
||||
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||
if (thing instanceof User) {
|
||||
const clientUser = this.searchClientByIdOrFail(thing.id);
|
||||
|
||||
const userMovedMessage = new UserMovedMessage();
|
||||
userMovedMessage.setUserid(clientUser.userId);
|
||||
userMovedMessage.setPosition(ProtobufUtils.toPositionMessage(clientUser.position));
|
||||
|
||||
const subMessage = new SubMessage();
|
||||
subMessage.setUsermovedmessage(userMovedMessage);
|
||||
|
||||
clientListener.emitInBatch(subMessage);
|
||||
//console.log("Sending USER_MOVED event");
|
||||
} else if (thing instanceof Group) {
|
||||
this.emitCreateUpdateGroupEvent(clientListener, thing);
|
||||
} else {
|
||||
console.error('Unexpected type for Movable.');
|
||||
}
|
||||
}
|
||||
|
||||
private onClientLeave(thing: Movable, listener:User) {
|
||||
const clientListener = this.searchClientByIdOrFail(listener.id);
|
||||
if (thing instanceof User) {
|
||||
const clientUser = this.searchClientByIdOrFail(thing.id);
|
||||
this.emitUserLeftEvent(clientListener, clientUser.userId);
|
||||
} else if (thing instanceof Group) {
|
||||
this.emitDeleteGroupEvent(clientListener, thing.getId());
|
||||
} else {
|
||||
console.error('Unexpected type for Movable.');
|
||||
}
|
||||
}*/
|
||||
|
||||
emitPlayGlobalMessage(client: ExSocketInterface, playglobalmessage: PlayGlobalMessage) {
|
||||
const pusherToBackMessage = new PusherToBackMessage();
|
||||
pusherToBackMessage.setPlayglobalmessage(playglobalmessage);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue