Closed mi-mazouz closed 3 years ago
@mi-mazouz, thanks for the feedback! Currently, there is not official timeout support. I am working on it. There is JS code that acts as a timeout listener/event, but it is not fully tested and might not work in all circumstances. In the meantime, this is a possible workaround:
function connect(options) {
return new Promise((resolve, reject) => {
const tcpTimeout = setTimeout(() => {
reject('Timeout');
}, 1000);
const tcpSocket = net.createConnection(options, () => {
clearTimeout(tcpTimeout);
resolve();
}
);
});
}
ok for the timeout but what about the connection error? What should happen if the connection fails?
@mi-mazouz, if you are setting an "incorrect" IP, you should get an 'error'
event with a message along the lines of "Host unreachable"
.
That's what I expected but I don't get this error
@mi-mazouz, can you reproduce the bug using the example code?
@Rapsssito Yes you should be able to reproduce it using my code
@mi-mazouz, I meant if you could reproduce the issue using the example code provided in the repository. You can comment out all the server references and test the client with your "incorrect" IP.
same with this code, nothing happened:
import React from 'react';
import {
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import TcpSocket from 'react-native-tcp-socket';
class App extends React.Component {
constructor(props) {
super(props);
this.updateChatter = this.updateChatter.bind(this);
this.state = { chatter: [] };
}
updateChatter(msg) {
this.setState({
chatter: this.state.chatter.concat([msg]),
});
}
componentDidMount() {
const serverPort = 53333;
const serverHost = '192.1.1.1';
// let server;
let client;
// server = TcpSocket.createServer((socket) => {
// this.updateChatter(`server connected on ${JSON.stringify(socket.address())}`);
// socket.on('data', (data) => {
// this.updateChatter(`Server Received: ${data}`);
// socket.write('Echo server\r\n');
// });
// socket.on('error', (error) => {
// this.updateChatter(`server client error ${error}`);
// });
// socket.on('close', (error) => {
// this.updateChatter(`server client closed ${error || ''}`);
// });
// }).listen({ port: serverPort, host: serverHost, reuseAddress: true }, (address) => {
// this.updateChatter(`opened server on ${JSON.stringify(address)}`);
// });
// server.on('error', (error) => {
// this.updateChatter(`Server error ${error}`);
// });
// server.on('close', () => {
// this.updateChatter('server close');
// });
client = TcpSocket.createConnection({
port: serverPort,
host: serverHost,
}, (address) => {
this.updateChatter(`opened client on ${JSON.stringify(address)}`);
client.write('Hello, server! Love, Client.');
});
client.on('data', (data) => {
this.updateChatter(`Client Received: ${data}`);
this.client.destroy(); // kill client after server's response
});
client.on('error', (error) => {
this.updateChatter(`client error ${error}`);
});
client.on('close', () => {
this.updateChatter('client close');
});
this.client = client;
}
componentWillUnmount() {
this.client = null;
}
render() {
return (
<View style={styles.container}>
<ScrollView>
{this.state.chatter.map((msg, index) => (
<Text key={index} style={styles.welcome}>
{msg}
</Text>
))}
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
export default App;
anyway, the setTimeout does the job!
@mi-mazouz, glad it works with setTimeout()
! I am not able to reproduce the issue, the device on your 192.168.1.1 may be accepting the TCP connection and keeping it on hold forever (that's why you don't get any error).
I will be releasing a setTimeout()
update soon (#56), it should work in all scenarios.
same when I change the ip and I don't have any device on 192.168.1.1
@mi-mazouz, what device are you using?
what do you mean? We use our own device but it does not change anything because the problem persists even if my device is off.
@mi-mazouz, I mean what device are you using to test the app: iPhone, Huawei, Pixel...
I'm testing with ios simulator
@mi-mazouz, I am able to reproduce the bug on iOS. Working on it.
hey @Rapsssito, do you have any news about this issue?
@mi-mazouz, I have not been able to figure it out yet. I have came into the conclusion that it might be related to GCDAsyncSocket
inner workings. I am still working on it. If you find anything, please let me know.
@Rapsssito Hi, I am running into a similar issue. Here is a snippet of my code. I followed your setTimeout example but my application crashes and runs into Error: Unhandled Error from my Samsung device. The function above is being called in a setInterval function. Update: App is not crashing anymore but after many calls from the setInterval, the socket gets stuck on a null error. Looks like the socket is not issuing a close/destroy.
function getTCPData() {
return new Promise((resolve, reject) => {
const tcpTimeout = setTimeout(() => {
reject('Timeout');
}, 1000);
const socket = TcpSocket.createConnection(
options,
() => {
clearTimeout(tcpTimeout);
// Write on the socket
socket.write('Ready for image');
},
socket.on('data', async function(data) {
// get json string
});
socket.on('error', function(error) {
socket.destroy();
});
socket.on('close', function() {
// if data received is valid json resolve, else reject
});
);
});
}
@ewc003, could you create a new issue with your specific problem?
@Rapsssito I'm facing similar issue, but not in all the devices only iOS 14 with iphone 7,8,XR , In iPhone 11 with iOS 14 working fine.
Issue is occurring at first time ,when you back and do create connection, connection created successfully.
@itzsankar I am currently working on a fix.
@Rapsssito Is there any update on this issue ?
@Santhosh-kumark, yes! I found the problem, but I am really busy at the moment. The fix might take a while.
@Santhosh-kumark @mi-mazouz, could you check if the issue still persists in the last version? I am testing on the iOS simulator without any timeout and after 1 minutes and 15 seconds I get an error in the error handler.
@Rapsssito I'm facing similar issue, but not in all the devices only iOS 14 with iphone 7,8,XR , In iPhone 11 with iOS 14 working fine.
Issue is occurring at first time ,when you back and do create connection, connection created successfully.
@Rapsssito Have you fixed this in the latest version?
@Rapsssito Mine was similar issue to https://github.com/Rapsssito/react-native-tcp-socket/issues/53#issuecomment-808131790 . Seems like this is not fixed in new version as well.
@itzsankar @Santhosh-kumark, could you check if you get an error response after 2 minutes?
I updated the package to the latest version and tested this code:
import React from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
import TcpSocket from 'react-native-tcp-socket';
class App extends React.Component {
constructor(props) {
super(props);
this.updateChatter = this.updateChatter.bind(this);
this.state = { chatter: ['hello'] };
}
updateChatter(msg) {
this.setState({
chatter: this.state.chatter.concat([msg]),
});
}
componentDidMount() {
const serverPort = 53333;
const serverHost = '192.1.1.3';
let client;
client = TcpSocket.createConnection({
port: serverPort,
host: serverHost,
}, (address) => {
this.updateChatter(`opened client on ${JSON.stringify(address)}`);
client.write('Hello, server! Love, Client.');
});
client.on('connect', () => {
this.updateChatter('Client connect');
console.log('CONNECT');
});
client.on('timeout', () => {
this.updateChatter('Client timeout');
console.log('TIMEOUT');
});
client.on('data', (data) => {
console.log('DATA');
this.updateChatter(`Client Received: ${data}`);
});
client.on('error', (error) => {
console.log('ERROR');
this.updateChatter(`client error ${error}`);
});
client.on('close', () => {
console.log('CLOSE');
this.updateChatter('client close');
});
this.client = client;
}
componentWillUnmount() {
this.client = null;
}
render() {
return (
<View style={styles.container}>
{this.state.chatter.map((msg, index) => (
<Text key={index} style={styles.welcome}>
{msg}
</Text>
))}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
},
welcome: {
fontSize: 20,
textAlign: 'center',
color: 'black',
margin: 10,
},
});
export default App;
and after 1 min and 15secs the error and close events were triggered so that's a good new.
@itzsankar @Santhosh-kumark, could you check if you get an error response after 2 minutes?
@Rapsssito , my problem is only in iPhone version other than 11 ,iOS 14 I'm not getting any response for first time, if I quit the app and connect it again, it is connecting perfectly. But in iPhone 11 with iOS 14 it is connecting for the first time itself without any issues. Lower iOS versions no problem.
@Rapsssito I think timeout is not working well, with the following code timeout and createConnection callback are triggered:
this._device = net.createConnection({
port: TCP_PORT,
host: deviceIp,
timeout: 1500,
}, (address) => {
console.log('CONNECTED', address);
resolve();
});
this._device.on('error', (error) => {
console.log('ERROR', error);
});
this._device.on('timeout', (error) => {
console.log('TIMEOUT', error);
});
this._device.on('data', dataListener);
if createConnection callback is triggered when the connection was successful timeout should not be triggered right?
my bad this_.device.removeListener('timeout') in createConnection callback did the job!
@mi-mazouz, I am glad it worked! If you agree, I think we can close this issue now. It has been a difficult problem to tackle.
@itzsankar, this issue has +30 comments right now. Could you please create a new issue with your problem, the devices with issues and a reproducible code?
@Rapsssito sure, I have created a new issue #106 we can track from there , let me know if you need any details
Description
Hello!!
I'm trying to create a tcp connection to an incorrect host (the ip is unreachable).
Here is my code:
Current behavior
this function never rejects or resolves.
Expected behavior
I expected to catch a connection error in the error event listener.
Relevant information
| react-native | 0.61.5 | | react-native-tcp-socket | 3.7.1 |