Skip to content

Commit

Permalink
fix: websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
naiba committed Dec 2, 2024
1 parent fc1dc11 commit df6c23a
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 105 deletions.
7 changes: 0 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"react-hook-form": "^7.53.1",
"react-i18next": "^15.1.2",
"react-router-dom": "^6.27.0",
"react-use-websocket": "^4.10.1",
"react-virtuoso": "^4.12.0",
"sonner": "^1.6.1",
"swr": "^2.2.5",
Expand Down
120 changes: 56 additions & 64 deletions src/components/fm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
import { IconButton } from "./xui/icon-button"
import { createFM } from "@/api/fm"
import { ModelCreateFMResponse, FMEntry, FMOpcode, FMIdentifier, FMWorkerData, FMWorkerOpcode } from "@/types"
import useWebSocket from "react-use-websocket"
import { toast } from "sonner"
import { ColumnDef } from "@tanstack/react-table"
import { Folder, File } from "lucide-react"
Expand Down Expand Up @@ -174,70 +173,63 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
}
}

const { sendMessage, getWebSocket } = useWebSocket(wsUrl, {
share: false,
onOpen: () => {
listFile();
},
onClose: (e) => {
console.log('WebSocket connection closed:', e);
},
onError: (e) => {
console.error(e);
toast("Websocket" + " " + t("Error"), {
description: t("Results.UnExpectedError"),
})
},
onMessage: async (e) => {
try {
const buf: ArrayBufferLike = e.data;

if (firstChunk.current) {
const identifier = new Uint8Array(buf, 0, 4);
if (arraysEqual(identifier, FMIdentifier.file)) {
worker.postMessage({ operation: 1, arrayBuffer: buf, fileName: currentBasename.current });
firstChunk.current = false;
} else if (arraysEqual(identifier, FMIdentifier.fileName)) {
const { path, fmList } = await fm.parseFMList(buf);
setPath(path);
setFMEntries(fmList);
} else if (arraysEqual(identifier, FMIdentifier.error)) {
const errBytes = buf.slice(4);
const errMsg = new TextDecoder('utf-8').decode(errBytes);
throw new Error(errMsg);
} else if (arraysEqual(identifier, FMIdentifier.complete)) {
// Upload completed
if (uOpen) setuOpen(false);
listFile();
} else {
throw new Error(t("Results.UnknownIdentifier"));
}
} else {
await waitForHandleReady();
worker.postMessage({ operation: 2, arrayBuffer: buf, fileName: currentBasename.current });
}
} catch (error) {
console.error('Error processing received data:', error);
toast("FM" + " " + t("Error"), {
description: t("Results.UnExpectedError"),
})
if (dOpen) setdOpen(false);
if (uOpen) setuOpen(false);
}
}
});

const socket = getWebSocket();
useEffect(() => {
if (socket && 'binaryType' in socket)
socket.binaryType = 'arraybuffer';
}, [socket])

const [currentPath, setPath] = useState('');
useEffect(() => {
listFile();
}, [currentPath])

const ws = new WebSocket(wsUrl);
ws.binaryType = 'arraybuffer';
ws.onopen = () => {
listFile();
}
ws.onclose = (e) => {
console.log('WebSocket connection closed:', e);
}
ws.onerror = (e) => {
console.error(e);
toast("Websocket" + " " + t("Error"), {
description: t("Results.UnExpectedError"),
})
}
ws.onmessage = async (e) => {
try {
const buf: ArrayBufferLike = e.data;

if (firstChunk.current) {
const identifier = new Uint8Array(buf, 0, 4);
if (arraysEqual(identifier, FMIdentifier.file)) {
worker.postMessage({ operation: 1, arrayBuffer: buf, fileName: currentBasename.current });
firstChunk.current = false;
} else if (arraysEqual(identifier, FMIdentifier.fileName)) {
const { path, fmList } = await fm.parseFMList(buf);
setPath(path);
setFMEntries(fmList);
} else if (arraysEqual(identifier, FMIdentifier.error)) {
const errBytes = buf.slice(4);
const errMsg = new TextDecoder('utf-8').decode(errBytes);
throw new Error(errMsg);
} else if (arraysEqual(identifier, FMIdentifier.complete)) {
// Upload completed
if (uOpen) setuOpen(false);
listFile();
} else {
throw new Error(t("Results.UnknownIdentifier"));
}
} else {
await waitForHandleReady();
worker.postMessage({ operation: 2, arrayBuffer: buf, fileName: currentBasename.current });
}
} catch (error) {
console.error('Error processing received data:', error);
toast("FM" + " " + t("Error"), {
description: t("Results.UnExpectedError"),
})
if (dOpen) setdOpen(false);
if (uOpen) setuOpen(false);
}
}

const listFile = () => {
const prefix = new Int8Array([FMOpcode.List]);
const pathMsg = new TextEncoder().encode(currentPath);
Expand All @@ -246,7 +238,7 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
msg.set(prefix);
msg.set(pathMsg, prefix.length);

sendMessage(msg);
ws.send(msg);
}

const downloadFile = (basename: string) => {
Expand All @@ -258,7 +250,7 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,
msg.set(prefix);
msg.set(filePathMessage, prefix.length);

sendMessage(msg);
ws.send(msg);
}

const uploadFile = async (file: File) => {
Expand All @@ -267,13 +259,13 @@ const FMComponent: React.FC<FMProps & JSX.IntrinsicElements["div"]> = ({ wsUrl,

// Send header
const header = fm.buildUploadHeader({ path: currentPath, file: file });
sendMessage(header);
ws.send(header);

// Send data chunks
while (offset < file.size) {
const chunk = file.slice(offset, offset + chunkSize);
const arrayBuffer = await fm.readFileAsArrayBuffer(chunk);
if (arrayBuffer) sendMessage(arrayBuffer);
if (arrayBuffer) ws.send(arrayBuffer);
offset += chunkSize;
}
}
Expand Down
58 changes: 25 additions & 33 deletions src/components/terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { AttachAddon } from "@xterm/addon-attach";
import { FitAddon } from '@xterm/addon-fit';
import { useRef, useEffect, useState } from "react";
import { sleep } from "@/lib/utils";
import useWebSocket from "react-use-websocket";
import { IconButton } from "./xui/icon-button";
import "@xterm/xterm/css/xterm.css";
import { createTerminal } from "@/api/terminal";
Expand All @@ -30,24 +29,22 @@ interface XtermProps {
const XtermComponent: React.FC<XtermProps & JSX.IntrinsicElements["div"]> = ({ wsUrl, setClose, ...props }) => {
const terminalRef = useRef<HTMLDivElement>(null);

const { sendMessage, getWebSocket } = useWebSocket(wsUrl, {
share: false,
onOpen: () => {
onResize();
},
onClose: () => {
terminal.dispose();
setClose(true);
},
onError: (e) => {
console.error(e);
toast("Websocket error", {
description: "View console for details.",
})
},
});

const socket = getWebSocket();
const ws = new WebSocket(wsUrl);
ws.binaryType = "arraybuffer";
ws.onopen = () => {
onResize();
}
ws.onclose = () => {
terminal.dispose();
setClose(true);
}
ws.onerror = (e) => {
console.error(e);
toast("Websocket error", {
description: "View console for details.",
})
}

const terminal = useRef(
new Terminal({
cursorBlink: true,
Expand Down Expand Up @@ -76,7 +73,7 @@ const XtermComponent: React.FC<XtermProps & JSX.IntrinsicElements["div"]> = ({ w
msg.set(prefix);
msg.set(resizeMessage, prefix.length);

sendMessage(msg);
ws.send(msg);
}
};

Expand All @@ -95,25 +92,20 @@ const XtermComponent: React.FC<XtermProps & JSX.IntrinsicElements["div"]> = ({ w
};

useEffect(() => {
if (socket && "binaryType" in socket && terminalRef.current) {
socket.binaryType = "arraybuffer";
const attachAddon = new AttachAddon(socket);

terminal.loadAddon(attachAddon);
terminal.loadAddon(fitAddon);

terminal.open(terminalRef.current);
}
if (!ws || !terminalRef.current) return;

const attachAddon = new AttachAddon(ws);
terminal.loadAddon(attachAddon);
terminal.loadAddon(fitAddon);
terminal.open(terminalRef.current);
window.addEventListener('resize', onResize);

return () => {
window.removeEventListener('resize', onResize);
if (socket) {
socket.close();
if (ws) {
ws.close();
}
};
}, [socket, terminal]);
}, [ws, terminal]);

return <div ref={terminalRef} {...props} />;
};
Expand Down

0 comments on commit df6c23a

Please sign in to comment.