Failed to fetch a worker script. VueJS application

1.8k views Asked by At

I've been trying to use a SharedWorker in a Vue application, but faced the error "Failed to fetch a worker script".

I want to use a SharedWorker to get and post messages to WebSocket.

socketworker.js

const API_KEY =
  "<my api key>";
const socket = new WebSocket(
  `wss://streamer.cryptocompare.com/v2?api_key=${API_KEY}`
);

self.onconnect = e => {
  const port = e.ports[0];

  socket.addEventListener("message", evt => {
    if (evt.data) {
      port.postMessage(evt.data);
      return;
    }
  });
};

self.onmessage = e => {
  message = e.data;

  socket.send(message);
};

api.js

const socketWorker = new SharedWorker("./workers/socketworker.js", {
  type: "module",
  name: "socketWorker"
});

socketWorker.port.onmessage = e => {
 ...
}

1

There are 1 answers

0
Felipe Barreiros On

I faced the same problem for a Vue SPA project and solved using "tabex" lib (https://github.com/nodeca/tabex)

This lib emits events based on localStorage changes for all tabs

This lib has a control of which is the "master" tab, so, you can connect to the websocket only on the master tab and send events to all tabs through the tabex.

// tabex-impl.ts

// @ts-nocheck
import * as tabex from 'tabex'
import {MasterTab} from "@/MasterTab";

window.tabex = tabex
window.tabex.router({
    // origin: [ '*://*.yourdomain.com', '*://yourdomain.com' ]
    origin: [ '*' ]
});

var live = window.tabex.client();

window.tabexLive = live

window.tabexLive.on('channel.name', function handler(message) {
    // Do something
    alert('do something!')
});

// Connect to messaging server when become master and
// kill connection if master changed
live.on('!sys.master', function (data) {
    console.log('!sys.master')
    console.log(data)

    if (data.node_id === data.master_id) {
        console.warn("I'm the master!")
        new MasterTab();
    }
});

The MasterTab control messages from websocket and throws through tabex

import store from "@/store";
import {AuthUserEntity} from "@/domain/entities/auth-user.entity";

export class MasterTab {
    private authEntity: AuthUserEntity;
    private socketConnection: WebSocket;

    constructor() {
        // only logged user can connect
        if(store.state.authEntity.user.id){
            this.authEntity = store.state.authEntity;
            if (!this.socketConnection) {
                this.socketConnect();
            }
        }
    }

    private socketConnect() {
        // const socket = new ClientSocket()
        const ws = new WebSocket('ws://localhost:9001')

        ws.onopen = () => {
            this.socketConnection = ws;
            this.setupSocket();
        }
    }

    private setupSocket() {
        this.socketConnection.onmessage = (message) => {
            console.warn('received message from socket!!!')
            //@ts-ignore
            window.tabexLive.emit('channel.name', 'message!', true);
        }
    }
}