fix: remove ajax method in dev env
parent
a0e364905d
commit
f47b952b38
|
@ -96,8 +96,7 @@ export default function Home() {
|
|||
|
||||
useEffect(() => {
|
||||
connect();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [connect]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!socket) return;
|
||||
|
@ -160,7 +159,11 @@ export default function Home() {
|
|||
>
|
||||
{!message.me && (
|
||||
<div className={classes.avatar}>
|
||||
<Avatar alt="User" color="blue" radius="xl">
|
||||
<Avatar
|
||||
alt={onlineUsers[message.from]}
|
||||
color="blue"
|
||||
radius="xl"
|
||||
>
|
||||
{onlineUsers[message.from] &&
|
||||
onlineUsers[message.from].length > 5
|
||||
? `${onlineUsers[message.from].slice(0, 1)}`
|
||||
|
|
|
@ -8,15 +8,15 @@ type Prop = {
|
|||
children: React.ReactNode;
|
||||
};
|
||||
export function AppProvider({ children }: Prop) {
|
||||
const [disconnect] = useSocketStore(({ disconnect }) => [disconnect]);
|
||||
const disconnect = useSocketStore((state) => state.disconnect);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("beforeunload", disconnect);
|
||||
return () => {
|
||||
console.log("disconnect");
|
||||
window.removeEventListener("beforeunload", disconnect);
|
||||
disconnect();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [disconnect]);
|
||||
|
||||
return (
|
||||
<RootStyleRegistry>
|
||||
|
|
|
@ -29,7 +29,6 @@ import {
|
|||
} from "@tabler/icons-react";
|
||||
import { SetStateAction, Dispatch, FC, useEffect, useState } from "react";
|
||||
import useSocketStore from "@/store/socket";
|
||||
import { environment } from "@/config";
|
||||
import Avatar from "./Avatar";
|
||||
|
||||
type Props = {
|
||||
|
@ -218,11 +217,7 @@ const ChatroomTitle: FC<Props> = ({ targetSocketId, setTargetSocketId }) => {
|
|||
</Menu.Target>
|
||||
|
||||
<Menu.Dropdown>
|
||||
<Menu.Label>
|
||||
{environment === "development"
|
||||
? "Not available" // in development mode, hide online user list because it's a server side feature
|
||||
: "Online user"}
|
||||
</Menu.Label>
|
||||
<Menu.Label>Online user</Menu.Label>
|
||||
{socket?.connected &&
|
||||
Object.keys(onlineUsers)
|
||||
.filter((socketId) => socketId !== socket?.id)
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import { NextApiResponseServerIO, SocketBroadcastMessage } from "@/types/next";
|
||||
import { NextApiRequest } from "next";
|
||||
|
||||
const broadcast = (req: NextApiRequest, res: NextApiResponseServerIO) => {
|
||||
if (req.method === "POST") {
|
||||
// get message
|
||||
const { from: sourceSocketId, timestamp, message } = req.body as SocketBroadcastMessage;
|
||||
console.log("PRODUCTION SERVER: Broadcast ", message)
|
||||
// dispatch to channel "message"
|
||||
res?.socket?.server?.io?.emit("broadcast", {
|
||||
from: sourceSocketId,
|
||||
message,
|
||||
timestamp,
|
||||
} as SocketBroadcastMessage);
|
||||
// return message
|
||||
res.status(201).json(message);
|
||||
}
|
||||
};
|
||||
|
||||
export default broadcast;
|
|
@ -1,33 +0,0 @@
|
|||
import { NextApiResponseServerIO, SocketPrivateMessage } from "@/types/next";
|
||||
import { NextApiRequest } from "next";
|
||||
|
||||
const private_message = (req: NextApiRequest, res: NextApiResponseServerIO) => {
|
||||
if (req.method === "POST") {
|
||||
// get message
|
||||
const {
|
||||
from: sourceSocketId,
|
||||
to: targetSocketId,
|
||||
timestamp,
|
||||
message,
|
||||
} = req.body as SocketPrivateMessage;
|
||||
|
||||
// dispatch to channel "message"
|
||||
res?.socket?.server?.io?.to(targetSocketId).emit("private_message", {
|
||||
from: sourceSocketId,
|
||||
to: targetSocketId,
|
||||
message,
|
||||
timestamp,
|
||||
} as SocketPrivateMessage);
|
||||
res?.socket?.server?.io?.to(sourceSocketId).emit("private_message", {
|
||||
from: sourceSocketId,
|
||||
to: targetSocketId,
|
||||
message,
|
||||
timestamp,
|
||||
} as SocketPrivateMessage);
|
||||
|
||||
// return message
|
||||
res.status(201).json(message);
|
||||
}
|
||||
};
|
||||
|
||||
export default private_message;
|
|
@ -9,6 +9,10 @@ export const config = {
|
|||
},
|
||||
};
|
||||
|
||||
const onlineUsers = new Map<string, string>();
|
||||
let isEmitting = false;
|
||||
let sendOnlineUsers: NodeJS.Timeout;
|
||||
|
||||
const socketio = async (req: NextApiRequest, res: NextApiResponseServerIO) => {
|
||||
if (!res.socket.server.io) {
|
||||
console.log("MOCK SERVER: First connect on socket.io");
|
||||
|
@ -18,10 +22,62 @@ const socketio = async (req: NextApiRequest, res: NextApiResponseServerIO) => {
|
|||
path: "/api/socket/socketio",
|
||||
addTrailingSlash: false,
|
||||
});
|
||||
io.on("connect", (socket) => {
|
||||
console.log("MOCK SERVER: SOCKET CONNECTED!", socket.id);
|
||||
}).on("disconnect", () => {
|
||||
console.log("MOCK SERVER: SOCKET DISCONNECTED!");
|
||||
io.on("connection", (socket) => {
|
||||
console.log("MOCK SERVER: user connected, online user count:", onlineUsers.size);
|
||||
|
||||
socket.on("join", (data) => {
|
||||
const { socketId, name = socketId } = data;
|
||||
onlineUsers.set(socketId, name);
|
||||
// console.log(
|
||||
// 'MOCK SERVER: user joined, online user count:',
|
||||
// 'socketId: ',
|
||||
// socketId,
|
||||
// 'name: ',
|
||||
// name,
|
||||
// );
|
||||
});
|
||||
|
||||
socket.on("broadcast", (broadcast, callback) => {
|
||||
console.log("MOCK SERVER: Broadcast ", broadcast);
|
||||
io.emit("broadcast", broadcast);
|
||||
if (callback) {
|
||||
callback({
|
||||
ok: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("private_message", (message, callback) => {
|
||||
console.log("MOCK SERVER: private_message", message);
|
||||
const { from: sourceSocketId, to: targetSocketId } = message;
|
||||
io.to(targetSocketId).emit("private_message", message);
|
||||
io.to(sourceSocketId).emit("private_message", message);
|
||||
if (callback) {
|
||||
callback({
|
||||
ok: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
onlineUsers.delete(socket.id);
|
||||
console.log(
|
||||
"MOCK SERVER: user disconnected, online user count:",
|
||||
onlineUsers.size
|
||||
);
|
||||
if (isEmitting && onlineUsers.size === 0) {
|
||||
clearInterval(sendOnlineUsers);
|
||||
isEmitting = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!isEmitting) {
|
||||
sendOnlineUsers = setInterval(
|
||||
() => io.emit("online_user", Object.fromEntries(onlineUsers)),
|
||||
5000
|
||||
);
|
||||
isEmitting = true;
|
||||
}
|
||||
});
|
||||
// append SocketIO server to Next.js socket server response
|
||||
res.socket.server.io = io;
|
||||
|
|
|
@ -12,8 +12,8 @@ type EmitModeDataTypes = {
|
|||
|
||||
type Store = {
|
||||
socket: null | Socket;
|
||||
emitMode: "broadcast" | "private_message";
|
||||
setEmitMode: (mode: "broadcast" | "private_message") => void;
|
||||
emitMode: keyof EmitModeDataTypes;
|
||||
setEmitMode: (mode: keyof EmitModeDataTypes) => void;
|
||||
emit: <T extends keyof EmitModeDataTypes>(event: T, data: EmitModeDataTypes[T]) => void;
|
||||
connect: () => void;
|
||||
disconnect: () => void;
|
||||
|
@ -33,21 +33,6 @@ const useSocketStore = create<Store>((set, get) => {
|
|||
* @param data - The data to send along with the event.
|
||||
*/
|
||||
emit: (event, data) => {
|
||||
// console.log("emit", event, data);
|
||||
// Check if environment is development
|
||||
if (environment === "development") {
|
||||
// Send a POST request to the /api/socket/${event} endpoint with the data
|
||||
fetch(`/api/socket/${event}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
}).catch((error) => {
|
||||
// Display an error message if there was an error sending the request
|
||||
if (error instanceof Error) toast.error(error?.message);
|
||||
});
|
||||
} else {
|
||||
const { socket } = get();
|
||||
if (!socket) return toast.error("Socket not connected");
|
||||
// This callback response needs to define on server at first.
|
||||
|
@ -56,7 +41,6 @@ const useSocketStore = create<Store>((set, get) => {
|
|||
// Display an error message if response.ok is false
|
||||
if (!response.ok) toast.error("Something went wrong");
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Connects to the socket server.
|
||||
|
|
Loading…
Reference in New Issue