New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React Native - URL.protocol is not implemented #195
Comments
Effectively the react native is unlikely to work - nats.ws is expecting a compliant ES w3c websocket environment. |
Can you polyfill this with https://www.npmjs.com/package/react-native-url-polyfill? |
you can try - I know that there are a few folks that have gotten older versions to work, but it is not clear if they got https://github.com/nats-io/nats.js to work or if it was https://github.com/nats-io/nats.ws. |
@aricart is there a recommended approach for integrating NATS with React Native? Certainly this is a common ask, no? |
It is not a very common ask, and it has been discussed that it should possibly be one of the supported clients. |
@jfols Work with that polyfill
yarn add fastestsmallesttextencoderdecoder nats.ws node-libs-react-native react-native-url-polyfill text-encoding-polyfill
module.exports = {
resolver: {
extraNodeModules: require('node-libs-react-native'),
},
...more config
};
/**
* Polyfills for nats.ws package
*/
import 'react-native-url-polyfill/auto';
import 'text-encoding-polyfill';
if (!Symbol.asyncIterator) {
Symbol.asyncIterator = Symbol.for('Symbol.asyncIterator');
} And that's all 🌟 |
Hi, anyone any tips on what the status is regarding working with nats on react-native? |
Hi @pietgk I worked with nats and react native, so far I've not seen any problem. In order to use it: import {connect, NatsConnection, consumerOpts} from 'nats.ws';
import {useCallback, useEffect, useRef} from 'react';
import {decode} from 'base-64';
const decodeMessageFromNatsServer = () => {
// YOUR LOGIC TO DECODE THE MESSAGE
}
const useNatsSubscription = ({
table,
onMessage,
}: {
table: string;
onMessage: (msg: object) => void;
}) => {
const nats = useRef<NatsConnection>();
const onSubscriptionMessage = useCallback(
async ({nameSubscription}: {nameSubscription: string}) => {
if (!nats.current) {
return;
}
const opts = consumerOpts({
name: 'MY_CHANNEL',
description: 'MY_CHANNEL_DESC',
});
opts.deliverNew();
opts.ackExplicit();
opts.manualAck();
nats.current
?.jetstream()
.pullSubscribe(nameSubscription, opts)
.then(async psub => {
psub?.pull({batch: 1});
for await (const m of psub) {
const payload = decodeMessageFromNatsServer(m);
if (payload) {
onMessage(payload);
}
m.ack();
psub.pull({batch: 1});
}
});
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[table],
);
const onSubscribe = useCallback(async () => {
try {
const nameSubscription = 'NAME_SUBSCRIPTION';
if (!nameSubscription) {
return;
}
// eslint-disable-next-line no-undef
const encoder = new TextEncoder();
const credentials = decode('NATS_USER_CRED_STRING');
const encodedCredentials = encoder.encode(credentials);
const nc = await connect({
debug: false,
servers: ['NATS_SERVER_ADDRESS'],
authenticator: encodedCredentials,
});
nats.current = nc;
await onSubscriptionMessage({nameSubscription});
} catch (error) {
console.log("ERROR: NATS Subscription", error);
}
}, []);
useEffect(() => {
onSubscribe();
return async () => {
await nats.current?.drain();
};
}, [onSubscribe]);
return {
onSubscribe,
};
};
export default useNatsSubscription;
// IN YOU COMPONENT
const sendedMessage = useRef(false);
const onRefresh = async () => {
// YOUT LOGIC
}
useNatsSubscription({
table: 'message',
onMessage: () => {
/* This code is part of a subscription to a NATS message queue. When a new message is received, it
checks if the `sendedMessage.current` flag is set to true. If it is, it means that the message
was sent by the current user and there is no need to refresh the conversation. If it is not
set, it calls the `onRefresh` function to refresh data with the new data/message. */
const refresh = async () => {
try {
if (sendedMessage.current) {
sendedMessage.current = false;
return;
}
await onRefresh(false);
} catch (error) {
} finally {
sendedMessage.current = false;
}
};
refresh().catch(error => console.log('on refresh', error));
},
}); |
It works, thank you so much mate! I tried to develop my own TCP library, it worked, but was pretty unstable. For other folks trying to fix this problem. You can follow steps above and start with this simple example to ensure that it works: https://nats.io/blog/getting-started-nats-ws/#reactjs Basically, once you are able to connect, you are good to go |
I had this hook to connect to nats server. I am working with TS and React Native.
I already tried this
The error I see in the console is: [ERROR: URL.protocol is not implemented]
React Native info
nats.ws version: 1.14.0
The text was updated successfully, but these errors were encountered: