Rapsssito / react-native-tcp-socket

React Native TCP socket API for Android, iOS & macOS with SSL/TLS support.
MIT License
304 stars 80 forks source link

Unable to work on functional component #102

Closed imAunAbbas closed 3 years ago

imAunAbbas commented 3 years ago

Description

I'm using React native's functional approach in my whole app and I'm trying to use react-native-tcp-socket in that components as well. But I'm facing different problems to handle the variables (I think so). Because there is no example available in the documentation that shows the use of the functional components.

Code:

I'm using these variables outside of my main function:

let server = null;
let client = null;
const MessageScreen = (props) => {
. . .
};

Inside my main function, I'm using these two functions to create and join TCP connections:

const _createTcpSocket = () => {
  server = TcpSocket.createServer((socket) => {
    updateChatter('server connected on ' + JSON.stringify(socket.address()));

    socket.on('data', (data) => {
      updateChatter('Server Received: ' + data);
      socket.write('Echo server\r');
    });

    socket.on('error', (error) => {
      updateChatter('server client error ' + error);
    });

    socket.on('close', (error) => {
      updateChatter('server client closed ' + (error ? error : ''));
    });
  }).listen({port: 45826, host: myIP, reuseAddress: true}, (address) => {
    updateChatter('opened server on ' + JSON.stringify(address));
  });

  server.on('error', (error) => {
    updateChatter('Server error ' + error);
  });

  server.on('close', () => {
    updateChatter('server close');
  });
};
const _joinTcpSocket = () => {
  client = TcpSocket.createConnection(
    {
      port: 45826,
      host: otherIP,
      localAddress: myIP,
      reuseAddress: true,
      // localPort: 20000,
      // interface: "wifi",
      // tls: true,
    },
    (address) => {
      updateChatter('opened client on ' + JSON.stringify(address));
      client.write('Hello, server! Love, Client.');
    },
  );

  client.on('data', (data) => {
    updateChatter('Client Received: ' + data);
    // client.destroy(); // kill client after server's response
    // server.close();
  });

  client.on('error', (error) => {
    updateChatter('client error ' + error);
  });

  client.on('close', () => {
    updateChatter('client close');
  });
};

Current behaviour

In my JSX, when I try to send the message from TextInput like this:

client.write(inputText);

It shows, TypeError: undefined is not an object (evaluating 'client.write')

This issue is because of the cleanup function of useEffect:

useEffect(() => {
  if (!check) {
    _createTcpSocket();
    _joinTcpSocket();
    setCheck(true);
  }
  return function cleanup() {
    server = null;
    client = null;
  };
});

But when I don't use the cleanup function, it works fine but only for the first time.

Expected behaviour

It should send the message as it does in the TcpSocket.createConnection. But instead, it is giving me errors. Kindly suggest to me any solution and also update the Documentation Example using a Functional Approach. Thanks

Relevant information

OS Android (only)
react-native 0.63.4
react-native-tcp-socket 4.5.5
Rapsssito commented 3 years ago

@imAunAbbas, I am sorry for your problem. It looks like your are experiencing an issue with the variable scope while using React custom hooks. Sadly, I cannot help you with that since it is not related to this module, but I would suggest you asking this question on stackoverflow or checking the available docs.

As an overall comment, I would guess that hooks do not access the global scope (which makes sense since a functional component should not have dependencies from other components). There are some tutorials about accessing global variables from a functional component.

imAunAbbas commented 3 years ago

@Rapsssito Glad, you responded. But all I'm asking is to update the documentation (whenever it is easy for you) and give an example using the functional component as well. Because this is confusing for those who prefer functional components over class components.

Rapsssito commented 3 years ago

@imAunAbbas, I have updated the example code so the App component just listen to the socket events. The socket and server instantiations are outside any React component. I feel that this satisfies a greater number of software design patters and might be clearer for the user.

imAunAbbas commented 3 years ago

Thanks for your help @Rapsssito by updating the library and giving the new example. At least my error TypeError: undefined is not an object (evaluating 'client.write') is gone because of the server and client initialization like this:

const server = new TcpSocket.Server();
const client = new TcpSocket.Socket();

As it is now clear that the server and client are not null when the app is started.

New Issue

But I'm facing a different kind of issue now. For the very first time when the app is built and I go to the specific screen containing this method works fine. But when I go back and come back again on this screen, this shows the error ERR_SERVER_ALREADY_LISTEN.

Scenario

I'm working on some sort of LAN chatting using the IP addresses in the local network (i.e. Contacts Screen). So it's like selecting an IP address (contact) and then goes to the chat screen where I'm using this library for the communication. When I go back to the Contacts Screen and come back again by selecting a different IP address (or even the same IP), it crashes and shows the error ERR_SERVER_ALREADY_LISTEN.

Conclusion

As both of my screens are in the same stack (React Navigation Stack), it is clear that this issue is not specific just to my problem. Anyone can face this issue who use this library in a scenario like this.

Any solution for this error?

Rapsssito commented 3 years ago

@imAunAbbas, I do not know exactly, but it sounds like you might be calling the listen() method each time you enter a contact the screen. Take a look at the server.listen() documentation.

github-actions[bot] commented 3 years ago

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community attention? This issue may be closed if no further activity occurs.