azure-sdk-for-js: [@azure/service-bus] Websocket connection failed with react native polyfills

  • Package Name: @azure/service-bus
  • Package Version: 7.7.1
  • Operating system:
  • nodejs
    • version:
  • browser
    • name/version:
  • react-native
    • name/version: 0.70.1
  • typescript
    • version: 4.8.3
  • Is the bug related to documentation in

Describe the bug I’m trying to run the service-bus client on a react native client. As suggested by the @azure/service-bus readme, I installed polyfills for the node core modules. I tried two ways:

  • manually resolving used packages to polyfills
//babel.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        alias: {
          crypto: 'crypto-browserify',
          process: 'process/browser',
          os: 'os-browserify/browser',
          dns: '@i2labs/dns',
          stream: 'stream-browserify',
          buffer: 'buffer',
          path: 'path-browserify',
        },
      },
    ],
  ],
};
}
  • Shimming with rn-nodeify
rn-nodeify --install process,path,os,stream,buffer,crypto,net,tls,assert,dns,dgram --hack

Both attempts result in the following WebSocket error:

ServiceBusError: Websocket connection failed.
    at construct (native)
    at Wrapper (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:23518:64)
    at construct (native)
    at _createSuperInternal (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:188184:406)
    at call (native)
    at MessagingError (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:188733:27)
    at construct (native)
    at _createSuperInternal (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:112719:406)
    at call (native)
    at ServiceBusError (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:116955:29)
    at translateServiceBusError (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:116997:33)
    at ?anon_0_ (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:122197:59)
    at throw (native)
    at asyncGeneratorStep (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:24748:26)
    at _throw (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:24774:29)
    at tryCallOne (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:53:16)
    at anonymous (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:139:27)
    at apply (native)
    at anonymous (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:31334:26)
    at _callTimer (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:31234:17)
    at _callReactNativeMicrotasksPass (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:31269:17)
    at callReactNativeMicrotasks (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:31477:44)
    at __callReactNativeMicrotasks (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:2869:46)
    at anonymous (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:2647:45)
    at __guard (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:2852:15)
    at flushedQueue (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:2646:21)
    at callFunctionReturnFlushedQueue (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=...:2628:33)

React Native does bring Websocket natively, so I was assuming to have similar, if not the same environment as in browsers, thus using browser polyfills. I’m a little clueless at this point though.

Thanks for any help.


By the way: The list of used core modules to polyfill in the readme is not correct because the package seems to use more core modules, i.e. crypto, dns, stream. Might add those to the readme.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@proohit it’s possible to reduce the polyfills required to five packages

  • buffer
  • path-browserify
  • process
  • os-browserfify
  • react-native-get-random-values

so the steps to add them are:

  • yarn add buffer os-browserify path-browserify process react-native-get-random-values
  • Modify metro.config.js
module.exports = {
  resolver: {
    extraNodeModules: {
      buffer: require.resolve('buffer/'),
      path: require.resolve('path-browserify'),
      process: require.resolve('process/browser.js'),
      os: require.resolve('os-browserify/browser.js'),
    },
  },
  // ...
}
  • App.tsx before importing Azure Service Bus SDK
global.Buffer = require('buffer').Buffer;
global.process = require('process');

import 'react-native-get-random-values';

I am closing this issue as the sample runs fine. Please let us know if you have further questions.

@proohit I just merged a PR to add a sample showing Event Hubs and Service Bus SDK usage in react-native. In this sample I used node-libs-react-native, which wraps a number of polyfills. I will probably try to reduce the set to the aboslutely required ones.

@proohit glad to hear that you got it running! Curious did you test on real hardware too, or just emulator?

Yes, some nodejs modules are not really used when running in browsers. However, since in previous versions, they are all required by the commonjs version, react-native packager or bundler would report error if they are not found during build time. We just merged a PR to allow importing asynchronously #23524. With this, we may be able to reduce the number of polyfills needed.

This worked! Got some incompatibilities with react-native-tcp and react-native-udp, but those are not related to this issue. After fixing all those, communication to service-bus was successful. Though, I would wish for a cleaner solution, without polyfilling almost all of node modules and being dependent on many (also outdated) dependencies.

@proohit I found something during my investigation: react-native’s WebSocket.binaryType by default is undefined, which is blocking rhea from behaving properly when running in browser. I will create an expo sample project where I got service-bus to send messages on Android Emulator. If you want, you can try and see whether this solves the connection issue you were seeing:

class WebSocketWrapper {
  constructor(...args) {
    const instance = new globalThis.WebSocket(...args);
    instance.binaryType = "blob";
    return instance;
  }
}

// then pass it via options

  const sbClient = new ServiceBusClient(connectionString, {
    webSocketOptions: {
      webSocket: WebSocketWrapper,
    },
  });