2024-04-06 02:35:31 +08:00
|
|
|
"use client";
|
2024-04-05 17:00:16 +08:00
|
|
|
import { useState, useEffect, useCallback } from "react";
|
2024-04-06 02:35:31 +08:00
|
|
|
import useWebSocket, { ReadyState } from "react-use-websocket";
|
2024-04-05 17:00:16 +08:00
|
|
|
|
2024-04-06 02:35:31 +08:00
|
|
|
const MOMO_IM_URL = "wss://live-ws.immomo.com/ws/im";
|
2024-04-05 17:00:16 +08:00
|
|
|
|
|
|
|
export const Danmu: React.FC = () => {
|
2024-04-06 02:35:31 +08:00
|
|
|
//Public API that will echo messages sent to it back to the client
|
|
|
|
const [socketUrl, setSocketUrl] = useState(MOMO_IM_URL);
|
|
|
|
const [messageHistory, setMessageHistory] = useState<MessageEvent<any>[]>([]);
|
|
|
|
|
|
|
|
// { "msg_id": 1, "client_time": 1712305590234, "type": "Sauth", "data": { "momoid": "404821828", "roomid": "14515460054", "role": 6, "isVisitor": false, "token": "97e721d0bd3bf2e63a9797f9daf50919", "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" } }
|
|
|
|
const { sendMessage, lastMessage, readyState } = useWebSocket(socketUrl, {
|
|
|
|
heartbeat: {
|
|
|
|
message: () => {
|
|
|
|
const pingMessage = {
|
|
|
|
msg_id: 2,
|
|
|
|
client_time: Date.now(),
|
|
|
|
type: "Ping",
|
|
|
|
data: {},
|
|
|
|
};
|
|
|
|
return JSON.stringify(pingMessage);
|
|
|
|
},
|
|
|
|
interval: 5000,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const momoId = "404821828";
|
|
|
|
const roomId = "14515460054";
|
|
|
|
const momoToken = "97e721d0bd3bf2e63a9797f9daf50919";
|
|
|
|
|
|
|
|
const clientTime = Date.now();
|
|
|
|
const data = {
|
|
|
|
msg_id: 1,
|
|
|
|
client_time: clientTime,
|
|
|
|
type: "Sauth",
|
|
|
|
data: {
|
|
|
|
momoid: momoId,
|
|
|
|
roomid: roomId,
|
|
|
|
role: 6,
|
|
|
|
isVisitor: false,
|
|
|
|
token: momoToken,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (ReadyState.OPEN === readyState) {
|
|
|
|
sendMessage(JSON.stringify(data));
|
2024-04-05 17:00:16 +08:00
|
|
|
}
|
2024-04-06 02:35:31 +08:00
|
|
|
}, [readyState]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (lastMessage !== null) {
|
|
|
|
if (lastMessage.data) {
|
|
|
|
const message = JSON.parse(lastMessage.data);
|
|
|
|
if (message.type === "pong") {
|
|
|
|
return;
|
2024-04-05 17:00:16 +08:00
|
|
|
}
|
2024-04-06 02:35:31 +08:00
|
|
|
setMessageHistory((prev) => prev.concat(message));
|
|
|
|
}
|
2024-04-05 17:00:16 +08:00
|
|
|
}
|
2024-04-06 02:35:31 +08:00
|
|
|
}, [lastMessage]);
|
|
|
|
|
|
|
|
const connectionStatus = {
|
|
|
|
[ReadyState.CONNECTING]: "Connecting",
|
|
|
|
[ReadyState.OPEN]: "Open",
|
|
|
|
[ReadyState.CLOSING]: "Closing",
|
|
|
|
[ReadyState.CLOSED]: "Closed",
|
|
|
|
[ReadyState.UNINSTANTIATED]: "Uninstantiated",
|
|
|
|
}[readyState];
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
{messageHistory.map((message, idx) => (
|
|
|
|
<MessageDispatcher key={idx} message={message} />
|
|
|
|
))}
|
|
|
|
<div className="chat chat-end">
|
|
|
|
<div className="chat-bubble">You underestimate my power!</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
2024-04-05 17:00:16 +08:00
|
|
|
|
2024-04-06 02:35:31 +08:00
|
|
|
const MessageDispatcher: React.FC<{ message: any }> = ({ message }) => {
|
|
|
|
const messageType = message?.groups?.[0]?.units?.[0]?.type;
|
|
|
|
let nick = "wait";
|
|
|
|
let content = "wait";
|
|
|
|
|
|
|
|
if (messageType === "Message") {
|
|
|
|
nick = message?.groups?.[0]?.nick;
|
|
|
|
content = message?.groups?.[0]?.units?.[0]?.["Msg.Message.data"]?.text;
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<div className="chat chat-start">
|
|
|
|
<div className="chat-bubble">
|
|
|
|
{nick}: {content}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|