Pusher - Shared web worker variable scope

590 views Asked by At

I'm using a shared worker for a pusher in Laravel, Here XYZABC is my pusher key as string, but is there a way I can use ENV variable or variables defined in my blade file so I don't have to hard-code key there, and also need to switch channels based on country. so is there a way to access java-script variables defined in blade inside a shared worker script? this is my code

This is the sample code from the pusher community I worked on

https://github.com/pusher-community/pusher-with-shared-workers

// Pusher notification works as shared worker thread for providing
// notification across different tab for the same user, thereby reducing 
// channel count per user

importScripts("../../common/pusher.worker.min.js");


// An array of the clients/tabs using this worker
var clients = [];


// Connect to Pusher
var pusher = new Pusher("XYZABC", {
    encrypted: true,
    cluster: 'ap2',
    useTLS : true
});


// Log pusher details to console
Pusher.logToConsole = true
// Subscribe to the channel we specified in our Laravel Event
var channel = pusher.subscribe('task-created');


// Bind a function to a Event (the full Laravel class)
channel.bind('App\\Events\\TaskCreated', function(data) {
    // Relay the message on to each client
    clients.forEach(function(client){
        client.postMessage(data);
    });
});


self.addEventListener("connect", function(evt){
    // Add the port to the list of connected clients
    var port = evt.ports[0];
    clients.push(port);

    // Start the worker.
    port.start();
});
1

There are 1 answers

0
aaabell On BEST ANSWER

After few research, found out workers can only communicate using postMessage or onmessage. so passed my key and country details on postMessage after worker start.

PS: Not sure if this is the correct work around or doing anything wrong here, do comment if there is better solution or mistake.

here's my Main thread

if (typeof(window.SharedWorker) === 'undefined') {
    throw("Your browser does not support SharedWorkers")
} else {
    // Start our new worker
    var worker = new SharedWorker(basePath+"/assets/frontend/js/pusher-worker.min.js");
    console.log('Worker:', worker);

    // Whenever we get a message, set the #message element to the data brought in
    worker.port.onmessage = function(evt){
        // Log's the data recieved from shared worked
        console.log(evt.data);
    };

    // If we get an error, log it out and close the worker.
    worker.onerror = function(err){
        console.log(err.message);
        worker.port.close();
    }

    // Start the worker.
    worker.port.start();

    // Post pusher key and country code to worker thread
    worker.port.postMessage({key : pusherkey, country : pusherHomeCountryCode});
}

here's my modified Worker thread

// Pusher notification works as shared worker thread for providing
// notification across different tab for same user, there by reducing 
// channel count per user

importScripts("../../common/pusher.worker.min.js");


// An array of the clients/tabs using this worker
var clients = [];

// Flag to initialize pusher only once
var initialize = false;

// These two variable value will be recieved on post message from main thread
var pusherKey = null;
var countryCode = null;

// Function to initialize pusher and subscribe to a channel
function initalizePusherFn(pusherKey, countryCode) {
    // Connect to Pusher
    var pusher = new Pusher(pusherKey, {
        encrypted: true,
        cluster: 'ap2',
        useTLS : true
    });


    // Log pusher details to console
    Pusher.logToConsole = true

    // Subscribe to the channel we specified in our Laravel Event
    var channelName = 'task-created';
    if(typeof countryCode != 'undefined' && countryCode != '' && countryCode != 'PH'){
        channelName = channelName+"-"+countryCode;
    }
    var channel = pusher.subscribe(channelName);

    // Bind a function to a Event (the full Laravel class)
    channel.bind('App\\Events\\TaskCreated', function(data) {
        // Relay the message on to each client
        clients.forEach(function(client){
            client.postMessage(data);
        });
    });
}

self.addEventListener("connect", function(evt){
    // Add the port to the list of connected clients
    var port = evt.ports[0];
    clients.push(port);

    // On first load a post message will be called to pass pusherkey and country
    port.addEventListener('message', function(eventM){
        var data = eventM.data;
        pusherKey = data.key;
        countryCode = data.country;

        console.log(' initialize value:', initialize, '\n');
        console.log(' key:', pusherKey, '\n');
        console.log(' country code: ', countryCode, '\n');
        
        // Check if pusher is already initialized,
        // if not initialize and subscribe to a channel based on country
        // this should onle be working once for multiple tabs, else channel and 
        // message count will increase for pusher
        if(!initialize)
            initalizePusherFn(pusherKey, countryCode);

        // set initialize as true after being initialized
        initialize = true;
    }, false);

    // Start the worker.
    port.start();
});