websocket object is not connecting the socket in react native - javascript

Hy, I'm trying to connect WebSocket in react-native but it's not connected on the first attempt. I have two screen users and a chat screen. On the users screen when I click on the user it navigates to chat screen.
According to the documentation of WebSocket
In order to communicate using the WebSocket protocol, you need to create a WebSocket object; this will automatically attempt to open the connection to the server.
I created the object like this:
const client = new W3CWebSocket(
'ws://url:port/api/ws/chat/1/' + logID + '/',
);
and complete look like this
const client = new W3CWebSocket(
'ws://url:port/api/ws/chat/1/' + logID + '/',
);
useFocusEffect(
useCallback(() => {
getID()
client.onopen = () => {
console.log('WebSocket Client Connected');
};
client.onmessage=(message)=>{
const dataFromServer = JSON.parse(message.data);
console.log('got reply! ', dataFromServer);
if(dataFromServer){
setMessages(messages => [
...messages,
{msg: dataFromServer.type, sender: dataFromServer.sender},
]);
}
}
scrollHandler();
return () => {
scrollHandler();
client.close()
};
}, []),
);
But it does not connect to the WebSocket, but when I do some changes on my code or say when I save the code file after opening the chat screen, it is connected. That's means when I navigate the screens from user->chat it does not connect but on coming to the chat screen I go back to vscode and code of chat screen just press ctrl+s it connects the socket. I also try it inside the useEffect or useFocusEffect but it still behaves the same.
How I can solve this problem?

Related

How to do 'signTransaction' after authenticated by 'signPersonalMessage' by WalletConnect of '#walletconnect/react-native-dapp'?

I am developing a react native mobile app where user can connect their existing wallet(rainbow, metamask and many more) to app.
I have already done the authentication part, like user can successfully connect their app wallet to app by this code.
import { useWalletConnect } from '#walletconnect/react-native-dapp';
const connector = useWalletConnect();
await connector.connect();
const message = `App name is XYZ - ${new Date().toUTCString()}`;
const hexMsg = convertUtf8ToHex(message);
const address = connector.accounts[0];
await setItemToStorage('address', address);
const msgParams = [hexMsg, address];
connector.signPersonalMessage(msgParams).then(async result => {
let data = {
message,
signature: result,
};
Now every thing is working as expected.
And then I have to transfer my wallet amount to other address, and to achieve this I know I have to get permission from wallet app,
To achieve this I am trying to do like
let txObj = {
gas: Web3js.utils.toHex(100000),
to: receiver_address!,
data: data,
from: userWallet,
};
console.log('Start transaction...');
const singTrasaction = await connector.signTransaction(txObj);
The connector.signTransaction(txObj) open the wallet app but not prompted me to confirm.
I am just confused and nothing get help me.
Please help me anyone I am getting stuck on this since a week.

When the page is opened for the first time the websocket is in the connecting state, and when the page is refreshed later, it switches to open state

I am trying to establish a websocket connection.
I'm writing the structure inside a useEffect in a context.
But there is one problem. When I open the page for the first time, the readyState of the websocket is not 1 in the console. 1 means open.
It comes as 0, that is, in the Connecting state. At the same time, when you write console.log to a function in socket.onclose event, it gives that console.
After the page is opened, when you refresh the page once, it makes the websocket connection.
You need to be able to control this situation. I wrote a few recursive solutions for this, but I could not find a solution.
export const NotificationsContext = createContext(initialState);
export const NotificationsProvider = (props) => {
useEffect(async () => {
let url = `http://localhost:8080/notifs`.replace('http', 'ws');
let socket = new WebSocket(url)
console.log(socket);
console.log(socket.readyState); // readyState is 0. mean CONNECTING.
socket.onclose = () => {
console.log('closed check') // in console.
socket = new WebSocket(url)
}
socket.onmessage = (data) => {
const notifData = JSON.parse(data.data);
console.log(notifData) // not in console.
}
console.log('connected');
}, []);
const [my_data, dispatch] = useReducer(userDetailsReducer, initialState);
return <NotificationsContext.Provider value={{ notifications, my_data, dispatch }}>.
{children}</NotificationsContext.Provider>;
};

window.solana not found in web3js

I want to connect a Solana wallet (phantom or any other) to a web application through the web3js library. I've read docs for most wallets and it seems like it's just as simple as await window.solana.request({ method: "connect" }); but window.solana is undefined in my case.
When I do console.log(window) I can see the Solana value with all its corresponding keys and values.
How can I do this?
I've found a working code that solved my issue. I am not sure what was the issue as I'm not very experienced with js, but the following code lets me connect to phantom.
I found this on StackOverflow on a similar thread, although I belive the original answer is missing some brackets.
Solana : Adding Sollet / Phantom Wallet Connect to my website - Steps?
const getProvider = async () => {
if ("solana" in window) {
await window.solana.connect(); // opens wallet to connect to
const provider = window.solana;
if (provider.isPhantom) {
console.log("Is Phantom installed? ", provider.isPhantom);
return provider;
}
} else {
document.write('Install https://www.phantom.app/');
}
};
window.onload = () => {
getProvider().then(provider => {
console.log('key', provider.publicKey.toString())
})
.catch(function(error){
console.log(error)
});
}
With your current implementation, everytime you refresh the app, you will get pop up to connect to the wallet. Instead you add {onlyIfTrusted:true} option to connect.
const getProvider = async () => {
if ("solana" in window) {
await window.solana.connect({onlyIfTrusted:true}); // opens wallet to connect to
const provider = window.solana;
if (provider.isPhantom) {
console.log("Is Phantom installed? ", provider.isPhantom);
return provider;
}
} else {
document.write('Install https://www.phantom.app/');
}
};
then instead of getting pop up when you reload the app, write a connection function to handle the connection when a user clicks on the button
const connectToWallet=async ()=>{
const {solana}=window
if(solana){
const response=await solana.connect()
console.log('address',response.publicKey.toString())
}
}
<button onClick={connectToWallet} >
Connect to Wallet
</button>
Now once user is connected, when you reload the app, it you wont get pop up to connect to the wallet
Is your website https enabled? If not then it won't work

How to connect to a host with peerjs?

I'm trying to use peerjs to connect an host with a client. I have two files (one for the host, one for the client). The host will generate a peerId which the client is using to connect to him. It's basically the tutorial from here.
host.html
const peer = new Peer()
peer.on('open', () => {
console.log('ID: ' + peer.id)
})
peer.on('connection', (conn) => {
conn.on('data', (data) => {
// Will print 'hi!'
console.log(data)
})
conn.on('open', () => {
conn.send('hello!')
})
})
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
client.html
const peer = new Peer()
const conn = peer.connect('1781a113-d095-4be5-9969-b80d9c364f6b')
conn.on('open', () => {
conn.send('hi!')
})
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
The client is not connecting nor sending messages. I tried to use their example to connect to my host and this was working. I was able to send messages to the host. What is the issue with my client?
It's a little vague in the documentation, but if you don't wait on the open event, messages to the server will be queued. I'm not sure if there is additional configuration needed to enable queuing, but simply waiting on the open event should work in your case
const peer = new Peer()
peer.on('open', () => {
const conn = peer.connect('1781a113-d095-4be5-9969-b80d9c364f6b')
conn.on('open', () => {
conn.send('hi!')
})
})
Keep in mind that the peer id generated in your 'host' will change every time you refresh the browser, so you might want to pick your own id instead of getting a random one

Apollo subscriptions - handling WS disconnects with subscribeToMore

I've been looking for a way to handle web socket disconnects in my React app with Apollo subscriptions and have not found a way to do so. The other examples I see in the apollo documentation show the below method for catching a reconnect:
const wsClient = process.browser ? new SubscriptionClient(WSendpoint, {
reconnect: true,
}) : null;
const wsLink = process.browser ? new WebSocketLink(wsClient) : null;
if (process.browser) {
wsLink.subscriptionClient.on(
'reconnected',
() => {
console.log('reconnected')
},
)
}
There are two issues with the above method:
is that is does not catch when the user disconnects from their internet (only from when the server restarts for whatever reason)
that the reconnect is triggered outside of my React apps components.
What I would like to be able to do is to is reload my "chat" component if the user either disconnects from their internet or if my express server goes down for any reason. For this to happen I would need my chat component to completely reload which i'm not sure would be possible from outside my component tree.
Is there a method in the Query or Subscription Apollo components to be able to capture this event and handle it accordingly from the component?
There are a few ways I can think of to handle these cases but none of them are a one-shot solution, each case needs to be handled independently.
Setup a online/offline listener (ref)
Setup an Apollo middleware to handle network errors from your server (ref)
Create a variable in your store, isOnline for example, which can hold a global reference of your app's state. Whenever the above two methods trigger, you could update the value of isOnline
Finally, to bundle all of it together. Create a react HOC which uses isOnline to handle the network state for each component. This can be used to handle network error messages, refresh components once network is restored.
You can use SubscriptionClient callbacks from subscriptions-transport-ws, like this:
const ws = require("ws");
const { SubscriptionClient } = require("subscriptions-transport-ws");
const { WebSocketLink } = require("apollo-link-ws");
const { ApolloClient } = require("apollo-client");
const { InMemoryCache } = require("apollo-cache-inmemory");
const subClient = new SubscriptionClient(
'ws://localhost:4000/graphql',
{ reconnect: true },
ws
);
subClient.onConnected(() => { console.log("onConnected") });
subClient.onReconnected(() => { console.log("onReconnected") });
subClient.onReconnecting(() => { console.log("onReconnecting") });
subClient.onDisconnected(() => { console.log("onDisconnected") });
subClient.onError(error => { console.log("onError", error.message) });
const wsLink = new WebSocketLink(subClient);
const client = new ApolloClient({
link: wsLink,
cache: new InMemoryCache()
});
I'm using this for Node.js, but it will probably work for React too.

Categories

Resources