Fix session problem
This commit is contained in:
parent
797a2885b5
commit
d3822fe933
|
@ -111,21 +111,12 @@ export class Channel {
|
|||
|
||||
let hasChangedChannel = false;
|
||||
|
||||
this.logger.debug("Has user?", this.hasUser(part));
|
||||
this.logger.debug("Has user?", this.hasUser(part._id));
|
||||
|
||||
// Is user in this channel?
|
||||
if (this.hasUser(part)) {
|
||||
// Alreay in channel, disconnect old
|
||||
|
||||
const oldSocket = findSocketByPartID(part.id);
|
||||
|
||||
if (oldSocket) {
|
||||
oldSocket.destroy();
|
||||
}
|
||||
|
||||
// Add to channel
|
||||
this.ppl.push(part);
|
||||
hasChangedChannel = true;
|
||||
if (this.hasUser(part._id)) {
|
||||
// Alreay in channel, add this part ID to IDs list
|
||||
// TODO
|
||||
} else {
|
||||
// Are we full?
|
||||
if (!this.isFull()) {
|
||||
|
@ -142,10 +133,12 @@ export class Channel {
|
|||
// Is user in any channel that isn't this one?
|
||||
for (const ch of channelList) {
|
||||
if (ch == this) continue;
|
||||
if (ch.hasUser(part)) {
|
||||
if (ch.hasUser(part._id)) {
|
||||
ch.leave(socket);
|
||||
}
|
||||
}
|
||||
|
||||
socket.currentChannelID = this.getID();
|
||||
}
|
||||
|
||||
this.logger.debug("Participant list:", this.ppl);
|
||||
|
@ -167,10 +160,10 @@ export class Channel {
|
|||
this.logger.debug("Leave called");
|
||||
const part = socket.getParticipant();
|
||||
|
||||
// Same as above...
|
||||
// Unknown side-effects, but for type safety...
|
||||
if (!part) return;
|
||||
|
||||
if (this.hasUser(part)) {
|
||||
if (this.hasUser(part._id)) {
|
||||
this.ppl.splice(this.ppl.indexOf(part), 1);
|
||||
}
|
||||
// TODO Broadcast channel update
|
||||
|
@ -199,8 +192,13 @@ export class Channel {
|
|||
return this.ppl;
|
||||
}
|
||||
|
||||
public hasUser(part: Participant) {
|
||||
const foundPart = this.ppl.find(p => p._id == part._id);
|
||||
public hasUser(_id: string) {
|
||||
const foundPart = this.ppl.find(p => p._id == _id);
|
||||
return !!foundPart;
|
||||
}
|
||||
|
||||
public hasParticipant(id: string) {
|
||||
const foundPart = this.ppl.find(p => p.id == id);
|
||||
return !!foundPart;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ export function createUserID(ip: string) {
|
|||
.substring(0, 24);
|
||||
}
|
||||
|
||||
export function createSocketID() {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
export function createColor(ip: string) {
|
||||
return (
|
||||
"#" +
|
||||
|
|
|
@ -9,6 +9,8 @@ import { loadConfig } from "../util/config";
|
|||
import { Gateway } from "./Gateway";
|
||||
import { Channel, channelList } from "../channel/Channel";
|
||||
import { ServerWebSocket } from "bun";
|
||||
import { findSocketByUserID, socketsBySocketID } from "./server";
|
||||
import { Logger } from "../util/Logger";
|
||||
|
||||
interface UsersConfig {
|
||||
defaultName: string;
|
||||
|
@ -22,6 +24,8 @@ const usersConfig = loadConfig<UsersConfig>("config/users.yml", {
|
|||
}
|
||||
});
|
||||
|
||||
const logger = new Logger("Sockets");
|
||||
|
||||
export class Socket extends EventEmitter {
|
||||
private id: string;
|
||||
private _id: string;
|
||||
|
@ -43,11 +47,29 @@ export class Socket extends EventEmitter {
|
|||
constructor(private ws: ServerWebSocket<unknown>) {
|
||||
super();
|
||||
this.ip = ws.remoteAddress; // Participant ID
|
||||
this.id = createID();
|
||||
|
||||
// User ID
|
||||
this._id = createUserID(this.getIP());
|
||||
// *cough* lapis
|
||||
|
||||
// Check if we're already connected
|
||||
// We need to skip ourselves, so we loop here instead of using a helper
|
||||
let foundSocket;
|
||||
|
||||
for (const socket of socketsBySocketID.values()) {
|
||||
if (socket == this) continue;
|
||||
|
||||
if (socket.getUserID() == this.getUserID()) {
|
||||
foundSocket = socket;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSocket) {
|
||||
// Use new session ID
|
||||
this.id = createID();
|
||||
} else {
|
||||
// Use original session ID
|
||||
this.id = foundSocket.id;
|
||||
}
|
||||
|
||||
this.loadUser();
|
||||
|
||||
|
@ -94,6 +116,7 @@ export class Socket extends EventEmitter {
|
|||
);
|
||||
|
||||
channel.join(this);
|
||||
|
||||
// TODO Give the crown upon joining
|
||||
}
|
||||
}
|
||||
|
@ -189,6 +212,7 @@ export class Socket extends EventEmitter {
|
|||
const foundCh = channelList.find(
|
||||
ch => ch.getID() == this.currentChannelID
|
||||
);
|
||||
|
||||
if (foundCh) foundCh.leave(this);
|
||||
}
|
||||
|
||||
|
|
124
src/ws/server.ts
124
src/ws/server.ts
|
@ -1,14 +1,6 @@
|
|||
// import {
|
||||
// App,
|
||||
// DEDICATED_COMPRESSOR_8KB,
|
||||
// HttpRequest,
|
||||
// HttpResponse,
|
||||
// WebSocket
|
||||
// } from "uWebSockets.js";
|
||||
import { Logger } from "../util/Logger";
|
||||
import { createUserID } from "../util/id";
|
||||
import { createSocketID, createUserID } from "../util/id";
|
||||
import fs from "fs";
|
||||
// import { join } from "path";
|
||||
import path from "path";
|
||||
import { handleMessage } from "./message";
|
||||
import { decoder } from "../util/helpers";
|
||||
|
@ -18,99 +10,28 @@ import env from "../util/env";
|
|||
|
||||
const logger = new Logger("WebSocket Server");
|
||||
|
||||
const usersByPartID = new Map<string, Socket>();
|
||||
export const socketsBySocketID = new Map<string, Socket>();
|
||||
|
||||
export function findSocketByPartID(id: string) {
|
||||
for (const key of usersByPartID.keys()) {
|
||||
if (key == id) return usersByPartID.get(key);
|
||||
for (const socket of socketsBySocketID.values()) {
|
||||
if (socket.getParticipantID() == id) return socket;
|
||||
}
|
||||
}
|
||||
|
||||
// Original uWebSockets code
|
||||
// export const app = App()
|
||||
// .get("/*", async (res, req) => {
|
||||
// const url = req.getUrl();
|
||||
// const ip = decoder.decode(res.getRemoteAddressAsText());
|
||||
// // logger.debug(`${req.getMethod()} ${url} ${ip}`);
|
||||
// // res.writeStatus(`200 OK`).end("HI!");
|
||||
// const file = join("./public/", url);
|
||||
export function findSocketByUserID(_id: string) {
|
||||
for (const socket of socketsBySocketID.values()) {
|
||||
logger.debug("User ID:", socket.getUserID());
|
||||
if (socket.getUserID() == _id) return socket;
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO Cleaner file serving
|
||||
// try {
|
||||
// const stats = lstatSync(file);
|
||||
|
||||
// let data;
|
||||
// if (!stats.isDirectory()) {
|
||||
// data = readFileSync(file);
|
||||
// }
|
||||
|
||||
// // logger.debug(filename);
|
||||
|
||||
// if (!data) {
|
||||
// const index = readFileSync("./public/index.html");
|
||||
|
||||
// if (!index) {
|
||||
// return void res
|
||||
// .writeStatus(`404 Not Found`)
|
||||
// .end("uh oh :(");
|
||||
// } else {
|
||||
// return void res.writeStatus(`200 OK`).end(index);
|
||||
// }
|
||||
// }
|
||||
|
||||
// res.writeStatus(`200 OK`).end(data);
|
||||
// } catch (err) {
|
||||
// logger.warn("Unable to serve file at", file);
|
||||
// logger.error(err);
|
||||
// const index = readFileSync("./public/index.html");
|
||||
|
||||
// if (!index) {
|
||||
// return void res.writeStatus(`404 Not Found`).end("uh oh :(");
|
||||
// } else {
|
||||
// return void res.writeStatus(`200 OK`).end(index);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .ws("/*", {
|
||||
// idleTimeout: 25,
|
||||
// maxBackpressure: 1024,
|
||||
// maxPayloadLength: 8192,
|
||||
// compression: DEDICATED_COMPRESSOR_8KB,
|
||||
|
||||
// open: ((ws: WebSocket<unknown> & { socket: Socket }) => {
|
||||
// ws.socket = new Socket(ws);
|
||||
// // logger.debug("Connection at " + ws.socket.getIP());
|
||||
|
||||
// usersByPartID.set(ws.socket.getParticipantID(), ws.socket);
|
||||
// }) as (ws: WebSocket<unknown>) => void,
|
||||
|
||||
// message: ((
|
||||
// ws: WebSocket<unknown> & { socket: Socket },
|
||||
// message,
|
||||
// isBinary
|
||||
// ) => {
|
||||
// const msg = decoder.decode(message);
|
||||
// handleMessage(ws.socket, msg);
|
||||
// }) as (
|
||||
// ws: WebSocket<unknown>,
|
||||
// message: ArrayBuffer,
|
||||
// isBinary: boolean
|
||||
// ) => void,
|
||||
|
||||
// close: ((
|
||||
// ws: WebSocket<unknown> & { socket: Socket },
|
||||
// code: number,
|
||||
// message: ArrayBuffer
|
||||
// ) => {
|
||||
// logger.debug("Close called");
|
||||
// ws.socket.destroy();
|
||||
// usersByPartID.delete(ws.socket.getParticipantID());
|
||||
// }) as (
|
||||
// ws: WebSocket<unknown>,
|
||||
// code: number,
|
||||
// message: ArrayBuffer
|
||||
// ) => void
|
||||
// });
|
||||
export function findSocketByIP(ip: string) {
|
||||
for (const socket of socketsBySocketID.values()) {
|
||||
if (socket.getIP() == ip) {
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const app = Bun.serve({
|
||||
port: env.PORT,
|
||||
|
@ -147,7 +68,7 @@ export const app = Bun.serve({
|
|||
(ws as unknown as any).socket = socket;
|
||||
logger.debug("Connection at " + socket.getIP());
|
||||
|
||||
usersByPartID.set(socket.getParticipantID(), socket);
|
||||
socketsBySocketID.set(createSocketID(), socket);
|
||||
},
|
||||
|
||||
message: (ws, message) => {
|
||||
|
@ -159,7 +80,14 @@ export const app = Bun.serve({
|
|||
logger.debug("Close called");
|
||||
const socket = (ws as unknown as any).socket as Socket;
|
||||
socket.destroy();
|
||||
usersByPartID.delete(socket.getParticipantID());
|
||||
|
||||
for (const sockID of socketsBySocketID.keys()) {
|
||||
const sock = socketsBySocketID.get(sockID);
|
||||
|
||||
if (sock == socket) {
|
||||
socketsBySocketID.delete(sockID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue