Skip to content

Problem using Web Worker in nodejs-mobile-cordova #172

@chiemekailo

Description

@chiemekailo
  • Project: nodejs-mobile-cordova
  • Version: 0.2.2
  • Mobile device 1: Android on Emulator - Android Nexus 5 API 25(Android 7.1.1, API 25)
  • Mobile device 2: iOS on Simulator - iPhone 5s (iOS 11.2)
  • Mobile OS and version: (Android 7.1.1, API 25) & (iOS 11.2)
  • Development Node.js: 11.6.0
  • Development platform: MacOS Majove 10.14.3 - Darwin Kernel Version 18.2.0: (RELEASE_X86_64 x86_64)

Problem using Web Worker in nodejs-mobile-cordova

Web Worker implementations for node-js appear to be incompatible with plugin.

Code

Client Side

  let blobToFile = (theBlob: Blob, fileName: string): File => {
    var b: any = theBlob;
    //A Blob() is almost a File() - it's just missing the two properties below which we will add
    b.lastModifiedDate = new Date();
    b.name = fileName;

    //Cast to a File() type
    return <File><any>theBlob;
  }

  //test function
  let finalBlob = new Blob([`( function sayHi() {

    var events = require('events');
    var eventEmitter = new events.EventEmitter();
    //Create an event handler & Assign the event handler to an event:
    eventEmitter.on('scream', function () {
      console.log('I hear a scream!');
    });
    
    //comment-out as necessary to test further.  
    self.onmessage = function (e) {
      console.log('I hear a scream! client b');
    };
    self.addEventListener('message', function(e) {
      console.log('I hear a scream! client c');
    });
  } )()`]);
  
  nodejs.channel.post( 'FloatingServerBridge', {  edge: 'translateSentences', blob: blobToFile(finalBlob, 'language-translate.js')  } );

Node-JS Side

const Worker = require("tiny-worker");  //npm install tiny-worker --save
cordova.channel.on('FloatingServerBridge', (msg) => {
  let worker =  new Worker( msg.blob );
  worker.postMessage('I hear a scream!');

  //Fire the 'scream' event:
  eventEmitter.emit('scream');
});

Expected behavior and actual behavior.

Expected Behavior

Console output -> I hear a scream!

Actual Behavior

iOS
No visible worker output, with console displaying the following error:

_GSRegisterPurpleNamedPortInPrivateNamespace Couldn't register <app_entity>.gsEvents with the bootstrap server. Error: unknown error code (1100).
This generally means that another instance of this process was already running or is hung in the debugger.

Android
No visible worker output

Solution Suggestion

Unfortunately, I am neither conversant with the inner workings of a JavaScript Web Worker API, nor that of the nodejs-mobile-cordova plugin.
I am pretty confident, though, that the problem is due to the fact that both APIs attempt to register the same event “message” on the same platform context (the nodejs-mobile-cordova plugin registers first of course, then the Web Worker tries and fails).
If this is the case, then

  1. Given that it is more precarious to try to change the JavaScript Web Worker “message” event, can you try to pre-fix same in the plugin or change it to something more plugin specific.
cordova.channel.on('message', (msg) => {
  console.log('[node] MESSAGE received: "%s"', msg);
});

becomes…

cordova.channel.on('nodejs-mobile-message', (msg) => {
  console.log('[node] MESSAGE received: "%s"', msg);
});
  1. Append a Web Worker-like api to the plugin that can be evoked from the concurrent node-js server in the “/www/nodejs-project/main.js” file. Like so:
  const Worker = require("nodejs-mobile-worker");  //installed along with the nodejs-mobile-cordova plugin.
  let worker =  new Worker( msg.blob );
  worker.postMessage('I hear a scream!');

Having suggested the priors, I note that an event can be registered multiple times in JavaScript, leading to a usually messy multiple run of the callback function when the event is fired. I wonder if it is only different in Node-JS, or the above is just not the case.

Steps to reproduce the problem.

  1. Set up an ionic3 app
  2. Install nodejs-mobile-cordova plugin
  3. Set up a concurrent node-js “express” server in the nodejs-mobile-cordova bridge, utilized within “/www/nodejs-project/main.js”. This should be the complete node server installation with a “node_modules” folder, and the modules included in the “package.json” file, all within the “/www/nodejs-project/“ folder. The Node-JS server code should be added within the main.js file.
  4. Add a standard Worker library via npm. I am using “tiny-worker”. (It works perfectly when standalone using command “node server-file.js”, and allows “require()” from within the worker.)
  5. Confirm all working. Just start up the nodejs-mobile-cordova as per design, and your “express” server is also started up and running concurrently.
  6. Add the above client side code to the “app.component.ts” file, inside the Platform.ready() call.
  7. Add the above node-js side code to the “/www/nodejs-project/main.js” file, standing on its own (that is, not within any function or event callback).
  8. Build app, run in simulator(iOS)/emulator(Android) and observe.

Ionic Project & NodeJS platform Specifications.

npm: 6.5.0-next.0
node: 11.6.0
angular: 5.2.9
ionic (Ionic CLI): 4.6.0
Ionic Framework: ionic-angular 3.9.2
@ionic/app-scripts: 3.2.1
cordova (Cordova CLI): 8.1.2 (cordova-lib@8.1.1)
Cordova Platforms: android 6.4.0, browser 5.0.3, ios 4.5.4
Android SDK Tools: 26.1.1 (/Users/chiemekailo/Library/Android/sdk)
ios-deploy: 1.9.4

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions