Well, sending messages took longer than it should have
This commit is contained in:
@@ -5,19 +5,25 @@ import QuillDB from "../_/quilldb.js"
|
||||
import Titles from "./model/Titles.js"
|
||||
import Members from './model/Members.js'
|
||||
import Tokens from './model/Tokens.js'
|
||||
import Posts from "./model/Posts.js"
|
||||
import Posts from "./model/Forum/Posts.js"
|
||||
import Conversations from "./model/Messages/Conversations.js"
|
||||
import Messages from "./model/Messages/Messages.js"
|
||||
|
||||
export default class Database {
|
||||
titles = new Titles()
|
||||
members = new Members()
|
||||
tokens = new Tokens()
|
||||
posts = new Posts()
|
||||
conversations = new Conversations()
|
||||
messages = new Messages()
|
||||
|
||||
fromID = {
|
||||
"HY": this.titles,
|
||||
"MEMBER": this.members,
|
||||
"TOKEN": this.tokens,
|
||||
"POST": this.posts
|
||||
"POST": this.posts,
|
||||
"CONVERSATION": this.conversations,
|
||||
"DM": this.messages
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@@ -51,7 +57,11 @@ export default class Database {
|
||||
}
|
||||
|
||||
}
|
||||
this.saveData()
|
||||
|
||||
setInterval(() => {
|
||||
console.log("saving db")
|
||||
global.db.saveData()
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
async saveData() {
|
||||
@@ -67,13 +77,19 @@ export default class Database {
|
||||
this.titles.entries,
|
||||
this.members.entries,
|
||||
this.tokens.entries,
|
||||
this.posts.entries
|
||||
this.posts.entries,
|
||||
this.conversations.entries,
|
||||
this.messages.entries
|
||||
|
||||
]
|
||||
let ids = [
|
||||
Object.entries(this.titles.ids),
|
||||
Object.entries(this.members.ids),
|
||||
Object.entries(this.tokens.ids),
|
||||
Object.entries(this.posts.ids),
|
||||
Object.entries(this.conversations.ids),
|
||||
Object.entries(this.messages.ids),
|
||||
|
||||
]
|
||||
for(let i=0; i<arrs.length; i++) {
|
||||
let arr = arrs[i]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import OrderedObject from "./OrderedObject.js"
|
||||
import OrderedObject from "../OrderedObject.js"
|
||||
const { z } = require("zod")
|
||||
|
||||
export default class Posts extends OrderedObject {
|
||||
@@ -11,6 +11,7 @@ export default class Members extends OrderedObject {
|
||||
city: z.string()
|
||||
})
|
||||
schema = z.object({
|
||||
id: z.number(),
|
||||
email: z.string().email(),
|
||||
firstName: z.string(),
|
||||
lastName: z.string(),
|
||||
@@ -26,7 +27,7 @@ export default class Members extends OrderedObject {
|
||||
isHashed = (s) => {return s.startsWith("$argon2")}
|
||||
|
||||
save(member) {
|
||||
let id = `MEMBER-${this.entries.length+1}`
|
||||
let id = `MEMBER-${member.id}`
|
||||
let result = this.schema.safeParse(member)
|
||||
if(result.success) {
|
||||
try {
|
||||
@@ -46,6 +47,7 @@ export default class Members extends OrderedObject {
|
||||
const hash = await argon2.hash(newMember.password);
|
||||
newMember.password = hash
|
||||
newMember.joined = global.currentTime()
|
||||
newMember.id = this.entries.length+1
|
||||
this.save(newMember)
|
||||
}
|
||||
|
||||
|
||||
62
server/db/model/Messages/Conversations.js
Normal file
62
server/db/model/Messages/Conversations.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import OrderedObject from "../OrderedObject.js"
|
||||
const { z } = require("zod")
|
||||
|
||||
export default class Conversations extends OrderedObject {
|
||||
|
||||
schema = z.object({
|
||||
id: z.number(),
|
||||
between: z.array(z.string()),
|
||||
lastUpdated: z.string()
|
||||
}).strict()
|
||||
|
||||
save(convo) {
|
||||
let id = `CONVERSATION-${convo.id}`
|
||||
let result = this.schema.safeParse(convo)
|
||||
if(result.success) {
|
||||
try {
|
||||
super.add(id, convo)
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
console.error(result.error)
|
||||
throw new global.ServerError(400, "Invalid Conversation Data!");
|
||||
}
|
||||
}
|
||||
|
||||
get(convoID) {
|
||||
console.log("convo getting, ", convoID)
|
||||
return this.entries[this.ids[convoID]]
|
||||
}
|
||||
|
||||
getByMember(userID) {
|
||||
let convos = []
|
||||
|
||||
function populateMemberProfilesFromIDs(ids) {
|
||||
let result = []
|
||||
for(let i=0; i<ids.length; i++) {
|
||||
result[i] = global.db.members.get(ids[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
for(let i=0; i<this.entries.length; i++) {
|
||||
let convo = this.entries[i]
|
||||
console.log(convo, userID)
|
||||
if(convo.between.includes(userID)) {
|
||||
|
||||
console.log("found user convo: ", convo.id)
|
||||
let messages = global.db.messages.getByConversation(`CONVERSATION-${convo.id}`)
|
||||
let result = {
|
||||
...convo,
|
||||
messages,
|
||||
}
|
||||
result.between = populateMemberProfilesFromIDs(convo.between)
|
||||
|
||||
convos.push(result)
|
||||
}
|
||||
}
|
||||
return convos
|
||||
}
|
||||
}
|
||||
57
server/db/model/Messages/Messages.js
Normal file
57
server/db/model/Messages/Messages.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import OrderedObject from "../OrderedObject.js"
|
||||
const { z } = require("zod")
|
||||
|
||||
export default class Messages extends OrderedObject {
|
||||
|
||||
schema = z.object({
|
||||
id: z.number(),
|
||||
conversation: z.string(),
|
||||
from: z.string(),
|
||||
text: z.string(),
|
||||
time: z.string()
|
||||
}).strict()
|
||||
|
||||
save(msg) {
|
||||
let id = `DM-${msg.id}`
|
||||
let result = this.schema.safeParse(msg)
|
||||
if(result.success) {
|
||||
try {
|
||||
super.add(id, msg)
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
console.error(result.error)
|
||||
throw new global.ServerError(400, "Invalid Conversation Data!");
|
||||
}
|
||||
}
|
||||
|
||||
add(convo, text, userID) {
|
||||
let newMessage = {}
|
||||
newMessage.time = global.currentTime()
|
||||
newMessage.from = userID
|
||||
newMessage.conversation = convo
|
||||
newMessage.text = text
|
||||
newMessage.id = this.entries.length+1
|
||||
console.log(newMessage)
|
||||
this.save(newMessage)
|
||||
}
|
||||
|
||||
getByConversation(convoID) {
|
||||
let result = []
|
||||
for(let i=0; i<this.entries.length; i++) {
|
||||
let entry = this.entries[i]
|
||||
if(entry.conversation = convoID) {
|
||||
let userID = entry.from
|
||||
let fromUser = global.db.members.get(userID)
|
||||
let newObj = {
|
||||
...entry
|
||||
}
|
||||
newObj.from = fromUser
|
||||
result.push(newObj)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -172,11 +172,6 @@ class Server {
|
||||
this.registerRoutes(router)
|
||||
app.use('/', router);
|
||||
|
||||
setInterval(() => {
|
||||
console.log("saving db")
|
||||
global.db.saveData()
|
||||
}, 5000)
|
||||
|
||||
const server = http.createServer(app);
|
||||
global.Socket = new Socket(server);
|
||||
const PORT = 3003;
|
||||
|
||||
@@ -17,7 +17,7 @@ export default class ForumHandler {
|
||||
static handleSend(msg, ws) {
|
||||
try {
|
||||
global.db.posts.add(msg.text, msg.forum, ws.userEmail)
|
||||
global.Socket.broadcast({event: "new-message", app: "FORUM", forum: msg.forum, msg: this.handleGet({forum: msg.forum, number: 100})})
|
||||
global.Socket.broadcast({event: "new-post", app: "FORUM", forum: msg.forum, msg: this.handleGet({forum: msg.forum, number: 100})})
|
||||
return {success: true}
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
|
||||
40
server/ws/handlers/MessagesHandler.js
Normal file
40
server/ws/handlers/MessagesHandler.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { z } = require("zod")
|
||||
|
||||
const sendSchema = z.object({
|
||||
conversation: z.string(),
|
||||
text: z.string(),
|
||||
})
|
||||
.strict()
|
||||
|
||||
export default class MessagesHandler {
|
||||
|
||||
static handleSend(msg, ws) {
|
||||
let user = global.db.members.getByEmail(ws.userEmail)
|
||||
let convo = global.db.conversations.get(msg.conversation)
|
||||
if(convo.between.includes(`MEMBER-${user.id}`)) {
|
||||
global.db.messages.add(msg.conversation, msg.text, `MEMBER-${user.id}`)
|
||||
global.Socket.broadcast({event: "new-message", app: "MESSAGES", msg: {conversationID: convo.id, messages: global.db.messages.getByConversation(`CONVERSATION-${msg.conversation}`)}})
|
||||
|
||||
} else {
|
||||
throw new Error("Can't add to a conversation user is not a part of!")
|
||||
}
|
||||
return {success: true}
|
||||
}
|
||||
|
||||
static handleGet(ws) {
|
||||
let user = global.db.members.getByEmail(ws.userEmail)
|
||||
let data = global.db.conversations.getByMember(`MEMBER-${user.id}`)
|
||||
return data
|
||||
}
|
||||
|
||||
static handle(operation, msg, ws) {
|
||||
switch(operation) {
|
||||
case "GET":
|
||||
return this.handleGet(ws)
|
||||
case "SEND":
|
||||
if(!sendSchema.safeParse(msg).success) throw new Error("Incorrectly formatted Forum ws message!")
|
||||
return this.handleSend(msg, ws)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ const { WebSocket, WebSocketServer } = require('ws');
|
||||
const { z } = require("zod")
|
||||
const jwt = require('jsonwebtoken');
|
||||
import ForumHandler from "./handlers/ForumHandler.js"
|
||||
import MessagesHandler from "./handlers/MessagesHandler.js"
|
||||
|
||||
export default class Socket {
|
||||
wss;
|
||||
@@ -12,8 +13,18 @@ export default class Socket {
|
||||
msg: z.union([
|
||||
z.object({}).passthrough(), // allows any object
|
||||
z.array(z.any()) // allows any array
|
||||
])
|
||||
}).strict()
|
||||
]).optional()
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
if (data.operation !== "GET" && data.msg === undefined) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ["msg"],
|
||||
message: "msg is required when operation is not GET"
|
||||
})
|
||||
}
|
||||
})
|
||||
.strict()
|
||||
|
||||
constructor(server) {
|
||||
this.wss = new WebSocketServer({ server });
|
||||
@@ -54,7 +65,7 @@ export default class Socket {
|
||||
try {
|
||||
const text = msg.toString();
|
||||
const req = JSON.parse(text);
|
||||
if(!this.messageSchema.safeParse(req).success) throw new Error("Socket.handleMessage: Incorrectly formatted incoming ws message!")
|
||||
if(!this.messageSchema.safeParse(req).success) throw new Error("Socket.handleMessage: Incoming ws message has incorrect format!")
|
||||
|
||||
let responseData;
|
||||
switch (req.app) {
|
||||
@@ -62,6 +73,10 @@ export default class Socket {
|
||||
responseData = ForumHandler.handle(req.operation, req.msg, ws)
|
||||
break;
|
||||
|
||||
case "MESSAGES":
|
||||
responseData = MessagesHandler.handle(req.operation, req.msg, ws)
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error("unknown ws message")
|
||||
}
|
||||
@@ -71,7 +86,7 @@ export default class Socket {
|
||||
}
|
||||
response.msg = responseData
|
||||
|
||||
if(!this.messageSchema.safeParse(response).success) throw new Error("Socket.handleMessage: Incorrectly formatted outgoing ws message!")
|
||||
if(!this.messageSchema.safeParse(response).success) throw new Error("Socket.handleMessage: Outgoing ws message has incorrect format!")
|
||||
ws.send(JSON.stringify(response))
|
||||
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user