import { useRef, useEffect } from 'react'; import vtkWSLinkClient from '@kitware/vtk.js/IO/Core/WSLinkClient'; import SmartConnect from 'wslink/src/SmartConnect'; import vtkRemoteView from '@kitware/vtk.js/Rendering/Misc/RemoteView'; vtkWSLinkClient.setSmartConnectClass(SmartConnect); function App() { const vtkContainerRef = useRef(null); const vtkRemoteViewRef = useRef(null); const vtkWSLinkClientRef = useRef(null); const connectedRef = useRef(false); const connectingRef = useRef(false); useEffect(() => { if (!connectingRef.current && !connectedRef.current) { const view = vtkRemoteView.newInstance({ rpcWheelEvent: 'viewport.mouse.zoom.wheel', }); vtkRemoteViewRef.current = view; if (vtkContainerRef.current && !view.getContainer()) view.setContainer(vtkContainerRef.current); view.getInteractor().setDesiredUpdateRate(100); view.setInteractiveRatio(1); view.setStillRatio(1); view.setInteractiveQuality(80); view.setStillQuality(80); const client = vtkWSLinkClient.newInstance(); vtkWSLinkClientRef.current = client; client.onConnectionReady(() => { connectedRef.current = true; }); client.onConnectionError((httpReq) => { const message = (httpReq && httpReq.response && httpReq.response.error) || `Connection error`; console.error(message); }); client.onConnectionClose((httpReq) => { const message = (httpReq && httpReq.response && httpReq.response.error) || `Connection close`; console.error(message); // To prevent crashing on mouse movement // once the server is closed if (view && !view.isDeleted()) { // console.log('Trying to avoid mouse move events here'); view.getInteractor().unbindEvents(view.getContainer()); } connectedRef.current = false; }); if (client && view) { const serverConfig = { application: 'Bar Chart Example', sessionURL: `ws://localhost:9261/ws`, secret: 'wslink-secret', }; console.log('connecting image stream'); client .connect(serverConfig) .then((validClient) => { const viewStream = validClient .getImageStream() .createViewStream('-1'); console.log('connected image stream'); const s = validClient.getConnection().getSession(); view.setViewStream(viewStream); view.setSession(s); view.render(); connectedRef.current = true; connectingRef.current = false; }) .catch((error) => { console.error('Image stream connection error', error); }) .finally(console.log); connectingRef.current = true; } } return () => { if (connectedRef.current) { const view = vtkRemoteViewRef.current; const client = vtkWSLinkClientRef.current; if (view && !view.isDeleted()) { const container = view.getContainer(); view.getInteractor().unbindEvents(container); view.getInteractor().delete(); // remove the 'canvas' and 'img' elements from container, as the new RemoteView instance (in the effect) will add them (in view.setContainer) // Fix for multiple canvas/img elements being added on every re-render const canvasEl = container.querySelector('canvas'); const imageEl = container.querySelector('img'); if (canvasEl) container.removeChild(canvasEl); if (imageEl) container.removeChild(imageEl); view.delete(); } if (client && !client.isDeleted()) { // !important: call this method to be able // to connect again after remounting client.getImageStream().disconnect(); client.disconnect(-1); // -1 to prevent server from quitting client.delete(); } console.log('disconnected image stream'); connectedRef.current = false; } }; }, []); return (
); } export default App;