Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions chat-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**/node_modules/
.env
dist/
.DS_Store
84 changes: 84 additions & 0 deletions chat-app/backend/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import express from "express";
import cors from "cors";

const app = express();
app.use(
cors({
// origin: "https://tzemingho-chatapp-server-frontend.hosting.codeyourfuture.io"
}),
);
app.use(express.json());
const port = 4000;

const waitingRoom = [];

const chatHistory = [
{
message: "Welcome to the channel.",
user: "System",
timestamp: new Date().getTime(),
},
];
Comment on lines +11 to +21
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could consider moving these declarations before const app = express();


app.get("/", (req, res) => {
res.json(chatHistory);
});

app.get("/messages", (req, res) => {
const since = parseInt(req.query.since);

if (isNaN(since)) {
return res.json(chatHistory);
}
const newMessages = chatHistory.filter(({ timestamp }) => timestamp > since);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An approach to reduce the amount of data sent in the response. Nicely done!


if (newMessages.length > 0) {
return res.json(newMessages);
}

const callback = (message) => res.json([message]);
waitingRoom.push(callback);

const seconds = 25;
const milliseconds = 1000;

const timeout = setTimeout(() => {
const index = waitingRoom.indexOf(callback);
if (index !== -1) {
waitingRoom.splice(index, 1);
res.send([]);
}
}, seconds * milliseconds);
Comment on lines +39 to +51
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me quite a while to figure out how the "waiting room" logic works. I think it is over complicated.

These scenarios may be difficult to reproduce consistently, but there is a possibility that the "waiting room" logic could break under the following conditions:

  • HTTP responses arrive out of order due to the asynchronous nature of request processing.
  • Multiple users post messages concurrently, causing two or more messages to receive the same timestamp.

No change needed.

});

app.post("/", (req, res) => {
try {
let { message, user } = req.body;
if (!message?.trim() || !user?.trim()) {
res.status(406).json({ error: "Empty message or user are not allowed." });
return;
} else {
const newTimestamp = new Date().getTime();
const newMessage = {
message: message,
user: user,
timestamp: newTimestamp,
};
chatHistory.push(newMessage);

while (waitingRoom.length > 0) {
const callback = waitingRoom.pop();
callback(newMessage);
}
res.status(201).send("sent");
}
} catch (error) {
console.error(`Failed to parse body as JSON: ${error}`);
res.status(400).json({ error: "Expected body to be JSON." });
return;
}
});

app.listen(port, () => {
console.log(`chatApp server is listening on port: ${port}`);
});
Loading
Loading