Search code examples
javascriptpublish-subscribepubnubreal-time-clock

How to show real timer clock in pubnub publish and subscribe method


        let timer =0;
    function showTime() {
        var d = new Date();
        document.getElementById("demo").innerHTML = d.toLocaleTimeString();
    }
    function letsGo(duration) {
        const pubnub = new PubNub({
            publishKey: 'pub-c-1bda0482-9e4d-4ae7-b95d-232b2d452050',
            subscribeKey: 'sub-c-e515c58a-69e0-11eb-b914-eedc703588a5',
            uuid: "myUniqueUUID"
        });
        var timer = duration;
            function  publishSampleMessage(){
                    var publishPayload ={
                        channel : "game-time",
                        message: {
                            data:setInterval(function () {
                            var  minutes, seconds;
                            if(timer>0)
                            {
                            minutes = parseInt(timer / 60, 10);
                            seconds = parseInt(timer % 60, 10);
                            minutes = minutes < 10 ? "0" + minutes : minutes;
                            seconds = seconds < 10 ? "0" + seconds : seconds;
                            //console.log(minutes+":"+seconds);
                            document.getElementById("demo").innerHTML = minutes + "m " + seconds + "s ";
                            timer--;                     
                            if (timer==0) {
                            
                                document.getElementById("demo").innerHTML ="Game is Over";
                                document.getElementById("game").innerHTML ="";                          
                            }
                            //timesender(timer);
                        }
                       
                    }, 1000),
                        mytime: --timer
                    }
                }
                pubnub.publish(publishPayload, function(status, response) {
                console.info("status publish function "+status);
                console.info("response publish function "+ response.timetoken);
                console.info(publishPayload);
                })
            }
            pubnub.addListener({
                status: function(statusEvent) {
                    if (statusEvent.category === "PNConnectedCategory") {
                        publishSampleMessage();
                    }
                },
                message: function(msg) {
                    console.log("sanu ki "+msg.message.data);
                   if(msg.message.mytime>0) {
                       console.log("tanu ki " + msg.message.mytime);
                       msg.message.mytime--;
                   }
                },
                presence: function(presenceEvent) {
                    // This is where you handle presence. Not important for now :)
                    console.log("presence "+presenceEvent.action);
                }
            })
            console.log("Subscribing...");
    
        pubnub.subscribe({
            channels: ['game-time'],
            withPresence: true
        });
        
    }
     function timesender(time){
                        console.log("time is this : "+time);
                    }

I am trying to publish a real-time countdown timer in PubNub through javascript but whenever I publish a message it appears something like a fixed number like 6 and it never appears like a countdown clock but in the console log it is appearing like a countdown clock. Please suggest me how to publish the countdown timer clock as an admin so that other users get listen to it. The basic idea is I have created an admin portal in PHP and JS where I am starting a countdown timer and unity mobile game users will be listening to that timer

Updated code after Stephen help:

     function letsGo(duration) {
            const channel = 'game-time';
            const pubnub = new PubNub({ publishKey : 'pub-c-1bda0482-9e4d-4ae7-b95d-232b2d452050', subscribeKey : 'sub-c-e515c58a-69e0-11eb-b914-eedc703588a5' });
            let countdown = 65; // seconds
            const countdownId = setInterval( countdownUpdate, 1000 );
            function countdownUpdate() {
                pubnub.publish({
                    channel : channel,
                    message : { 'countdown' : --countdown },
                });
                if (countdown <= 0) clearInterval(countdownId);
            }

        console.log("Subscribing...");

// Public user receiving updates on the countdown
            pubnub.subscribe({
                channels: [channel]
            });

            pubnub.addListener({ message: event => {
                    const timeLeft = event.message.countdown;
                    console.log("time left "+timeLeft)
                    const minutes = Math.floor(timeLeft / 60) + '';
                    const seconds = Math.floor(timeLeft % 60) + '';
                    let dd = `${minutes.padStart(2,'0')}:${seconds.padStart(2,'0')}`;
                    document.querySelector('#demo').innerHTML =
                        `${minutes.padStart(2,'0')}:${seconds.padStart(2,'0')}`;
                }});

}

I am getting a minor problem now. As basically I have created a letsGo function on a click button so whenever I am opening a timer page in another browser I am getting two clocks one is the continuation of the previous browser but there is another one that is getting started from beginning again


Solution

  • JavaScript Countdown Timer

    The bug in the code: an int eventId value is published via PubNub. This isn't the intended design. The reason for this is explained following usage of setInterval function returning the eventId for the interval timer.

    let eventId = setInterval(...) returns an integer that references the setInterval eventId on the browser's event loop stack. The idea is that you can use the eventId to stop the interval later on with clearInterval(eventId).

    JavaScript Countdown Timer

    Recommended Approach:

    (()=>{
    'use strict';
    
    const channel = 'game-time';
    const pubnub = new PubNub({ publishKey : 'demo', subscribeKey : 'demo' });
    let countdown = 65; // seconds
    const countdownId = setInterval( countdownUpdate, 1000 );
    
    // Secure Server --> this should be running on your node.js server.
    function countdownUpdate() {
        pubnub.publish({
            channel : channel,
            message : { 'countdown' : --countdown },
        });
        if (countdown <= 0) clearInterval(countdownId);
    }
    
    // Public user receiving updates on the countdown
    pubnub.subscribe({
        channels: [channel]
    });
    
    pubnub.addListener({ message: event => {
        const timeLeft = event.message.countdown;
        const minutes = Math.floor(timeLeft / 60) + '';
        const seconds = Math.floor(timeLeft % 60) + '';
        document.querySelector('#timer').innerHTML =
            `${minutes.padStart(2,'0')}:${seconds.padStart(2,'0')}`;
    }});
    
    })();
    #timer {
        font-size: 60px;
    }
    <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.29.11.min.js"></script>
    <div id="timer">00:00</div>