danmu-sim/app/music/danmu.tsx
2024-04-05 17:00:16 +08:00

96 lines
3.1 KiB
TypeScript

'use client';
import { useState, useEffect, useCallback } from "react";
import useWebSocket, { ReadyState } from 'react-use-websocket';
const MOMO_IM_URL = 'wss://live-ws.immomo.com/ws/im'
export const Danmu: React.FC = () => {
//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));
}
}, [readyState])
useEffect(() => {
if (lastMessage !== null) {
if (lastMessage.data) {
const message = JSON.parse(lastMessage.data);
if (message.type === 'pong') {
return;
}
setMessageHistory((prev) => prev.concat(message));
}
}
}, [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>
);
};
// TODO
const MessageDispatcher: React.FC = ({ 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>)
};