Socket working only with debug mode react native - sockets

My socket emit works properly only on debug mode, when i tried with release APK nothing happened.
Code to connect socket -
socket = io(SOCKET_URL, {
transports: ['websocket'],// you need to explicitly tell it to use websockets
forceNew: true,
jsonp: false
});
socket.on('connect', () => {
console.log('connected!');
});
socket.on('disconnect', () => {
console.log('disconnect!');
});
Code to emit event
socket.emit('LIVE_MSG', { msg: "asdfasasdf3" }, (res) => {
console.log(res);
})
I have tried many options with socket connection i.e. timeout, setting and removing jsonp
Also tried with window.navigator.userAgent = "react-native";
But the result is none, socket only emits event when it is in debug mode, gone mad why it is not working with release apk.
Please help.

If you don't specify url, socket set url as localhost.
https://socket.io/get-started/chat/
"Notice that I’m not specifying any URL when I call io(), since it defaults to trying to connect to the host that serves the page."
(I'm not familiar with socet.io.)

Related

How to Connect to localhost Mongodb using an emulator?

First time making a question here so sorry for anything that isn't clear.
Basically I took a react course that set up a functional site with crud and now I'm trying to set up something similar in react native. So I'm new to react, react-native, and mongodb; basically everything I'm working with. This is for self study as well, so just trying to expand my skills.
This is the code that works in my react app under server.js from the backend
const client = await MongoClient.connect("mongodb://localhost:27017", {
useUnifiedTopology: true,
});
//api inbetween these two
app.listen(8000, () => console.log("Listening on port 8000"));
On my front end in my package.json I have this
"proxy": "http://localhost:8000/",
from my understanding this basically lets my frontend "proxy"/mask itself as if its coming from port 8000. Then I can call it using a url like below.
useEffect(() => {
const fetchData = async () => {
const result = await fetch(`/api/articles/${name}`);
const body = await result.json();
setArticleInfo(body);
};
fetchData();
}, [name]);
In my react-native app I get an unhandled promise rejection and in postman I get an internal 500 error with no associated error seems to be null since nothing is printed. Doing some research, I think the issue is because now I'm running this app on an emulator so I think it can't identify the main computer or localhost?
I've tried changing the localhost part of the address to my ipv4 address, to the expo connection url, 0.0.0.0, and also to what I believe is the android localhost 10.0.2.2 but none of them seems to work. example of android localhost change.
server.js
const client = await MongoClient.connect("mongodb://10.0.2.2:27017", {
useUnifiedTopology: true,
});
//api inbetween these two
app.listen(8000, () => console.log("Listening on port 8000"));
package.json
"proxy": "http://10.0.2.2:8000/",
When it's set to 10.0.2.2 postman times out and the app still has the unhandled promise error.
When it's set to 0.0.0.0 postman returns a 500 error with no details and the app still has the unhandled promise error.
When it's set to the expo url it straight up doesn't work.
When its set to my ipv4 address I get the unhandled promise and postman returns this error
"error": {
"name": "MongoServerSelectionError",
"reason": {
"type": "Single",
"setName": null,
"maxSetVersion": null,
"maxElectionId": null,
"servers": {},
"stale": false,
"compatible": true,
"compatibilityError": null,
"logicalSessionTimeoutMinutes": null,
"heartbeatFrequencyMS": 10000,
"localThresholdMS": 15,
"commonWireVersion": null
}
}
Posts I've looked at
Connect to MongoDB Atlas Cluster db with react-native app
Mongodb connection with react native form
React Native / Expo : Fetch throws “Network request failed”
why do we use 10.0.2.2 to connect to local web server instead of using computer ip address in android client
Your useEffect is wriiten wrong
Write it like this
useEffect(() => {
GetArticles(); // Called whenever there's a change in name
}, [name]);
// Create this function outside useEffect
const GetArticles = async () => {
try {
// Also in your fetch you have yo write url like this
const result = await fetch(
`http://${YOUR_IPv4_ADDRESS}:8000/api/articles/${name}`
);
const body = await result.json();
setArticleInfo(body);
} catch (error) {
console.log(error);
}
};
Also this is 100% correct
const client = await MongoClient.connect("mongodb://localhost:27017", {
useUnifiedTopology: true,
});
//api inbetween these two
app.listen(8000, () => console.log("Listening on port 8000"));
Don't change it to this
const client = await MongoClient.connect("mongodb://10.0.2.2:27017", {
useUnifiedTopology: true,
});
//api inbetween these two
app.listen(8000, () => console.log("Listening on port 8000"));

Flutter: simple socket.io testing - Websocket pending

I have a super simple socket.io node server like below
// Socket!
io.on("connection", (socket) => {
console.log("a user connected");
socket.on("msg", (aaa) => {
console.log(aaa);
});
socket.on("fromServer", (_) => print(_));
console.log(socket.handshake.query)
});
And, here is my Flutter code to connect to the server
// Dart client
IO.Socket socket = IO.io(
'http://192.168.219.102:7199',
IO.OptionBuilder()
.setTransports(['polling'])
.disableAutoConnect()
.setQuery({"hee": 'asdf'})
.build());
socket.connect();
socket.onConnect((_) {
print(_);
});
On the network tab, I see two requests
101 HTTP 490ms
101 WS Pending
When I connect to the socket.io server from the other node.js server, I see the console.log of a user connected on the terminal. However, I see nothing from Flutter.
What can I do to receive the socket message on the server and connect the device.

RabbitMQ Publish to Exchange Confirmation

I would like to return a retrieve a confirmation that the message was successfully published to the exchange before closing the AMQP connection. At the moment, I am using a timeout function to allow for the message to be published before closing the connection. This is not the right way. Can someone please help to retrieve a confirmation so I can close the connection based on a successful publish?
The code I am using is below:
function toExchange(msg)
{
amqp.connect('amqp://localhost:5672', function(err, conn) //local connection
{
conn.createChannel(function(err, ch)
{
var exchange = 'MessageExchange';
ch.assertExchange(exchange, 'fanout', {durable: true});
ch.publish(exchange, '', new Buffer(msg));
console.log("Sent to Exchange: %s", msg);
});
setTimeout(function() { conn.close(); }, 5000);
});
}
You can use a RabbitMQ extension called "Publisher confirms". Here is more information: https://www.rabbitmq.com/confirms.html#publisher-confirms.
You are not notified when the message is published to the exchange, but when it is published and routed to all queues: https://www.rabbitmq.com/confirms.html#when-publishes-are-confirmed
In your case using amqplib in nodeJS you can use this snippet of code: https://www.squaremobius.net/amqp.node/channel_api.html#confirmchannel
It uses the callback #waitForConfirms(function(err) {...}) that triggers when all published messages have been confirmed.

Mongo connection occasionally makes the lambda function timeout

I have been using MLab MongoDB and mongoose library to create a db connection inside a serverless (Lambda) handler. It works smoothly on local machine. But sometimes it doesn't work after deployment.The request returns an Internal server error. The weird thing is sometimes it works. But If I remove the database connection code, the handler works. The serverless log just says Process exited before completing request. No real errors so no idea what to do.
The db connection looks like this:
handler.js
// Connect to database
mongoose.connect(process.env.DATABASE_URL, {
useMongoClient: false
}).then((ee) => {
console.log('------------------------invoke db ', ee);
})
.catch(err => console.error('-----------error db ', err));
No error in here too. Any idea what's happening?
When you get Process exited before completing request, it means that the node process has crashed before Lambda was able to call callback. If you go to Cloudwatch logs, there would be an error and stack trace of what happened.
You should connect to the MongoDB instance inside your handler and before you call callback(), disconnect first.
It would be like this...
exports.handler = (event, context, callback) => {
let response;
return mongoose.connect(process.env.DATABASE_URL, {
useMongoClient: false
}).then((ee) => {
// prepare your response
response = { hello: 'world' }
}).then(() => {
mongoose.disconnect()
}).then(() => {
// Success
callback(null, response)
}).catch((err) => {
console.error(err);
callback(err);
})
};
Here is an article explaining with details how lambda work with node and an example of how to implement DB connection.
Differently of #dashmug suggested, you should NOT disconnect your DB since connecting every time will decrease your performance.

How to know my socket connect is success or not?

I want to do something when the nodejs server is started or I will do something else not related to the server.
But how could I know that. There is no property that shows the status of the connection, and because the socket is asynchronous that I can't get the err by try..catch...
The following is my clinet code.
var socket = io.connect('http://localhost:3000/monitor');
socket.on('message', function (data) {
console.log(data);
});
Anyone can tell me how to if(is connected).. else.. in this place?
Try listening to the following events:
socket.on( 'connect', function() {
});
socket.on( 'disconnect', function() {
});
socket.on( 'connect_failed', function() {
});
socket.on( 'error', function() {
});
Socket.io has some bugs in firing some events so it's better to listen to all of those that might mean a connection failed.