Skip to content

NIce Dcv SDK React slow

0

So i am using react nice dcv sdk this works fine, but when i enter the nice dcv session, this is extremely slow in responding to clicks, so i can for example click on something in the dcv window, i don't see anything happen, but when i reload and go back, then i see what i clicked on opened, same thing when i am typing. there seem to be something wrong with the sdk.

But if i access it directly with IP:PORT on my browser, this works fine without the delay issue

i have a backend controller like this:

import { Request, Response } from 'express';
import { sendError } from '../../../utils/restErrors';

module.exports = {
    async FetchStreamingByName(req: Request, res: Response) {
        try {
            const serverUrl = 'https://54.145.241.208:8080'; //for testing purpose
            const { name } = req.params;
            const data = [
                {
                    serverUrl,
                    name: 'dcv-default',
                },
                {
                    serverUrl,
                    name: 'tz-owncloud',
                },
            ];

            const filteredData = data.filter((item) => item.name === name);

            if (filteredData.length === 0) {
                return sendError(
                    res,
                    'No data found.',
                    404,
                    'FetchAllStreamings - No data found.',
                );
            }

            return res.status(200).json({
                data: filteredData[0],
            });
        } catch (err: any) {
            console.error(`Error while fetching data: ${err.message}`);
            return sendError(
                res,
                err.message,
                500,
                'FetchAllStreamings - Error while fetching data.',
            );
        }
    },
};

the frontend looks like this:

import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import dcv from "./dcvjs-esm/dcv";
import "@cloudscape-design/global-styles/index.css";
import { DCVViewer } from "./dcv-ui/dcv-ui";
import { getStream } from '../../api/dcvController';
//took off the unnessary import for this sample 

const LOG_LEVEL = dcv.LogLevel.INFO;
let auth;

const TzRender = () => {
    const user = useSelector((state) => state.user);
    const sessionName = "elliot";
    const [message, setMessage] = useState('');
    const [authenticated, setAuthenticated] = useState(false);
    const [sessionId, setSessionId] = useState("");
    const [authToken, setAuthToken] = useState("");
    const [credentials, setCredentials] = useState({});
    const [sdkLoaded, setSdkLoaded] = useState(false);
    const [serverUrl, setServerUrl] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const [streamStatus, setStreamStatus] = useState('Initializing Stream...');
    const [errorMessage, setErrorMessage] = useState('');
    const [fullScreen, setFullScreen] = useState(false);
    const [connected, setConnected] = useState(false);

    const fetchStreamData = async () => {
        try {
            if(!connected){
                const response = await getStream('tz-owncloud');
                if (response.status === 200) {
                    const data = response.data.data;
                    setServerUrl(data.serverUrl);
                }
            }
        } catch (error) {
            console.error('Error fetching data:', error);
            setErrorMessage('Failed to fetch stream data.');
        }
    };

    useEffect(() => {
        if(!connected){
            fetchStreamData();
        }
    }, [connected]);

    const onSuccess = (_, result) => {
        // console.log(result);
        // const session = result.find(element => element.sessionId === sessionName);
        if (result.length > 0) {
            setSessionId(result[0].sessionId);
            setAuthToken(result[0].authToken);
            setAuthenticated(true);
            setIsLoading(false);
            setConnected(true);
        } else {
            setErrorMessage('Session ID not found');
            setIsLoading(false);
        }
    };

    const onPromptCredentials = (_, credentialsChallenge) => {
        const requestedCredentials = credentialsChallenge.requiredCredentials.reduce((acc, challenge) => {
            acc[challenge.name] = "";
            return acc;
        }, {});
        setCredentials(requestedCredentials);
    };

    const authenticate = () => {
        dcv.setLogLevel(LOG_LEVEL);
        setStreamStatus('Authenticating ...');
        setIsLoading(true);

        const attemptCount = 0;
        const maxAttempts = 15;
        const retryInterval = 1000;

        const tryAuthenticate = async (count) => {
            if (count >= maxAttempts) {
                setIsLoading(false);
                setErrorMessage('Failed to retrieve server URL in time. Please try again.');
                return;
            }

            if (!serverUrl && !connected) {
                fetchStreamData();
                setTimeout(() => tryAuthenticate(count + 1), retryInterval);
                return;
            }

            const auth = dcv.authenticate(serverUrl, {
                promptCredentials: onPromptCredentials,
                error: onError,
                success: onSuccess,
            });

            if (auth.url) {
                setStreamStatus('Authenticating...');
                setTimeout(() => {
                    if (!authenticated) {
                        setIsLoading(false);
                        setErrorMessage('Failed to authenticate. Please try again.');
                    }
                }, 20000);
            } else {
                setIsLoading(false);
                setErrorMessage('Failed to start authentication. Please try again.');
            }
        };

        tryAuthenticate(attemptCount);
    };

    const updateCredentials = (e) => {
        const { name, value } = e.target;
        setCredentials(prev => ({
            ...prev,
            [name]: value,
        }));
    };

    const submitCredentials = (e) => {
        e.preventDefault();
        auth.sendCredentials(credentials);
    };

    useEffect(() => {
        if (!authenticated && sdkLoaded) {
            authenticate();
        }
    }, [authenticated, sdkLoaded, serverUrl]);

    const handleDisconnect = (reason) => {
        auth.retry();
        setAuthenticated(false);
    };

    const loadSdkAndRender = () => {
        setSdkLoaded(true);
        setIsLoading(true);
    };

    const resizeDisplay = () => {
        const displayFrame = document.getElementById("dcv-display-frame");
        const display = document.getElementById("dcv-display");
        const dcvContainer = document.getElementById("dcv-container");

        if (dcvContainer && displayFrame && display) {
            dcvContainer.style.width = "100vw";
            dcvContainer.style.height = "100vh";
            displayFrame.style.width = "100vw";
            displayFrame.style.height = "100vh";
            displayFrame.style.overflow = "hidden";
            displayFrame.style.position = "absolute";
            displayFrame.style.top = "0";
            displayFrame.style.left = "0";
            displayFrame.style.zIndex = "1";

            display.style.width = "100vw";
            display.style.height = "100vh";
            display.style.position = "absolute";
            display.style.top = "0";
            display.style.left = "0";
            display.style.zIndex = "1";
            display.style.margin = "0"; // Ensure there's no margin
            display.style.outline = "none"; // Remove any outline
        }
    };

    useEffect(() => {
        if (authenticated && sdkLoaded) {
            resizeDisplay();
        }
    }, [authenticated, sdkLoaded]);

    const toggleFullscreen = () => {
        const elem = document.documentElement;

        if (!document.fullscreenElement) {
            if (elem.requestFullscreen) {
                elem.requestFullscreen();
            } else if (elem.mozRequestFullScreen) { /* Firefox */
                elem.mozRequestFullScreen();
            } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
                elem.webkitRequestFullscreen();
            } else if (elem.msRequestFullscreen) { /* IE/Edge */
                elem.msRequestFullscreen();
            }
        }
        setFullScreen(true);
    };

    const onError = (_, error) => {
        console.error(`Error during the authentication: ${error.message}`);
        setErrorMessage(error.message);
        setIsLoading(false);
    };

    return (
        <BGContainer>
            {!sdkLoaded && (
                <Button variant="PinkButton" 
                    label="Jump In" 
                    disable={isLoading}
                    onClick={loadSdkAndRender} />
            )}
            {errorMessage && sdkLoaded && !isLoading && !authenticated && (
                <Typography variant="pWhite" margin={'3rem 0 3rem 0'}>
                    {errorMessage}
                </Typography>
            )}
            {sdkLoaded && isLoading && (
                <Loader>
                    <Logo src={PinkIntraverseWithoutBorderLogo} alt="Intraverse Logo" />
                    <Typography variant="pWhite" margin={'3rem 0 3rem 0'}>
                        {streamStatus}
                    </Typography>
                    <AnimatedBoxes/>
                </Loader>
            )}
            {sdkLoaded && !isLoading && authenticated && (
                <>
                {!fullScreen && (
                    <FullscreenButton onClick={toggleFullscreen}>⛶</FullscreenButton>
                )}
                <DCVViewer
                    dcv={{
                        sessionId,
                        authToken,
                        serverUrl,
                        onDisconnect: handleDisconnect,
                        logLevel: LOG_LEVEL,
                    }}
                    uiConfig={{
                        toolbar: {
                            visible: true,
                            fullscreenButton: true,
                            multimonitorButton: true,
                        },
                    }}
                    style={{
                        width: "100%",
                        height: "100%",
                    }}
                />
                </>
            )}
        </BGContainer>
    );
};

const getBackgroundImage = () => {
    const env = process.env.REACT_APP_STREAM_API_ENV;

    const bgMap = {
        production: prodBG,
        staging: stagingBG,
        development: devBG,
        demo: demoBG
    };

    return bgMap[env] || demoBG; // Default to demoBG if the env isn't matched
};

export default TzRender;

const BGContainer = styled.div`
    background-image: url(${getBackgroundImage()});
    background-size: cover;
    height: 100vh;
    width: 100vw;
    display: flex;
    justify-content: center;
    align-items: center;
`;

const Loader = styled.div`
    color: white;
    font-size: 24px;
    padding: 20px; 
    border-radius: 5px;
    background-color: rgba(0, 0, 0, 0.5); 
    width: 30vw; 
    height: 50vh; 
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    border: 1px solid #968dfd;
`;

const Logo = styled.img`
    display: block;
    align-self: center;
    width: 20%;
    height: auto;
`;

const FullscreenButton = styled.button`
    position: absolute;
    top: 20px;
    right: 20px;
    z-index: 10;
    background: transparent;
    color: white;
    border: none;
    border-radius: 5px;
    padding: 10px;
    cursor: pointer;
    font-size: 18px;
    
    &:hover {
        background-color: rgba(0, 0, 0, 0.9);
    }
`;

probably something is wrong somewhere that i cannot idenitify

asked 2 years ago226 views

1 Answer
0
import React, { useState, useEffect, useCallback } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import dcv from "./dcvjs-esm/dcv";
import { getStream } from '../../api/dcvController';

const LOG_LEVEL = dcv.LogLevel.INFO;

const TzRender = () => {
    const user = useSelector((state) => state.user);
    const [message, setMessage] = useState('');
    const [authenticated, setAuthenticated] = useState(false);
    const [sessionId, setSessionId] = useState("");
    const [authToken, setAuthToken] = useState("");
    const [credentials, setCredentials] = useState({});
    const [sdkLoaded, setSdkLoaded] = useState(false);
    const [serverUrl, setServerUrl] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const [streamStatus, setStreamStatus] = useState('Initializing Stream...');
    const [errorMessage, setErrorMessage] = useState('');
    const [connected, setConnected] = useState(false);

    const fetchStreamData = useCallback(async () => {
        try {
            const response = await getStream('tz-owncloud');
            if (response.status === 200) {
                const data = response.data.data;
                setServerUrl(data.serverUrl);
            }
        } catch (error) {
            setErrorMessage('Failed to fetch stream data.');
        }
    }, []);

    useEffect(() => {
        if (!connected) {
            fetchStreamData();
        }
    }, [connected, fetchStreamData]);

    const onSuccess = (_, result) => {
        if (result.length > 0) {
            setSessionId(result[0].sessionId);
            setAuthToken(result[0].authToken);
            setAuthenticated(true);
            setIsLoading(false);
            setConnected(true);
        } else {
            setErrorMessage('Session ID not found');
            setIsLoading(false);
        }
    };

    const onPromptCredentials = (_, credentialsChallenge) => {
        const requestedCredentials = credentialsChallenge.requiredCredentials.reduce((acc, challenge) => {
            acc[challenge.name] = "";
            return acc;
        }, {});
        setCredentials(requestedCredentials);
    };

    const authenticate = useCallback(() => {
        dcv.setLogLevel(LOG_LEVEL);
        setStreamStatus('Authenticating...');
        setIsLoading(true);

        const tryAuthenticate = async () => {
            if (!serverUrl || !connected) {
                await fetchStreamData();
                return;
            }

            const auth = dcv.authenticate(serverUrl, {
                promptCredentials: onPromptCredentials,
                error: onError,
                success: onSuccess,
            });

            if (!auth.url) {
                setIsLoading(false);
                setErrorMessage('Failed to start authentication. Please try again.');
            }
        };

        tryAuthenticate();
    }, [serverUrl, connected, fetchStreamData]);

    const onError = (_, error) => {
        console.error(`Error during the authentication: ${error.message}`);
        setErrorMessage(error.message);
        setIsLoading(false);
    };

    useEffect(() => {
        if (!authenticated && sdkLoaded) {
            authenticate();
        }
    }, [authenticated, sdkLoaded, serverUrl, authenticate]);

    const loadSdkAndRender = () => {
        setSdkLoaded(true);
        setIsLoading(true);
    };

    const resizeDisplay = () => {
        const displayFrame = document.getElementById("dcv-display-frame");
        const display = document.getElementById("dcv-display");
        const dcvContainer = document.getElementById("dcv-container");

        if (dcvContainer && displayFrame && display) {
            dcvContainer.style.width = "100vw";
            dcvContainer.style.height = "100vh";
            displayFrame.style.width = "100vw";
            displayFrame.style.height = "100vh";
            displayFrame.style.overflow = "hidden";
            displayFrame.style.position = "absolute";
            displayFrame.style.top = "0";
            displayFrame.style.left = "0";
            displayFrame.style.zIndex = "1";

            display.style.width = "100vw";
            display.style.height = "100vh";
            display.style.position = "absolute";
            display.style.top = "0";
            display.style.left = "0";
            display.style.zIndex = "1";
            display.style.margin = "0"; // Ensure there's no margin
            display.style.outline = "none"; // Remove any outline
        }
    };

    useEffect(() => {
        if (authenticated && sdkLoaded) {
            resizeDisplay();
        }
    }, [authenticated, sdkLoaded]);

    const toggleFullscreen = () => {
        const elem = document.documentElement;
        if (!document.fullscreenElement) {
            elem.requestFullscreen?.() || elem.mozRequestFullScreen?.() || elem.webkitRequestFullscreen?.() || elem.msRequestFullscreen?.();
        }
    };

    return (
        <BGContainer>
            {!sdkLoaded && (
                <Button variant="PinkButton" label="Jump In" disable={isLoading} onClick={loadSdkAndRender} />
            )}
            {errorMessage && sdkLoaded && !isLoading && !authenticated && (
                <Typography variant="pWhite" margin={'3rem 0 3rem 0'}>
                    {errorMessage}
                </Typography>
            )}
            {sdkLoaded && isLoading && (
                <Loader>
                    <Logo src={PinkIntraverseWithoutBorderLogo} alt="Intraverse Logo" />
                    <Typography variant="pWhite" margin={'3rem 0 3rem 0'}>
                        {streamStatus}
                    </Typography>
                    <AnimatedBoxes />
                </Loader>
            )}
            {sdkLoaded && !isLoading && authenticated && (
                <>
                    <FullscreenButton onClick={toggleFullscreen}>⛶</FullscreenButton>
                    <DCVViewer
                        dcv={{
                            sessionId,
                            authToken,
                            serverUrl,
                            onDisconnect: handleDisconnect,
                            logLevel: LOG_LEVEL,
                        }}
                        uiConfig={{
                            toolbar: {
                                visible: true,
                                fullscreenButton: true,
                                multimonitorButton: true,
                            },
                        }}
                        style={{
                            width: "100%",
                            height: "100%",
                        }}
                    />
                </>
            )}
        </BGContainer>
    );
};

export default TzRender;

answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.