react-native-zeroconf: Unspecified error when phone put to sleep during zeroconf scan

Been using the library with a recent project and very satisfied with how easy to implement it was.

However, in tightening things up recently, I’ve noticed that zeroconf seems to be responsible for two types of crashes in my app.

  1. When the app is minimized as the user navigates to the home screen. Error is encountered on resuming the app.

  2. When the phone is put to sleep by pressing the power button. Error once again encountered on resuming the app.

In both cases, the error is an ‘Uncaught, unspecified “error” event. (10)’ with the following log

Unhandled JS Exception: Uncaught, unspecified "error" event. (-72000)
2017-01-05 16:01:20.156716 Tavern[310:44322] [] nw_socket_get_input_frames recvmsg(fd 7, 1024 bytes): [57] Socket is not connected
2017-01-05 16:01:20.241348 Tavern[310:44322] [] nw_socket_get_input_frames recvmsg(fd 10, 1024 bytes): [57] Socket is not connected
2017-01-05 16:01:20.248243 Tavern[310:44322] [] nw_endpoint_handler_add_write_request [8.1 192.168.1.25:8081 failed socket-flow (satisfied)] cannot accept write requests
2017-01-05 16:01:20.249545 Tavern[310:43888] [] __tcp_connection_write_eof_block_invoke Write close callback received error: [22] Invalid argument

Both errors only occur when a react-native-zeroconf scan is actively running. Disabling zeroconf or stopping the scan prevents the errors.

I was able to work around the first type of crash by writing some code to stop the zeroconf scan when the app is moved to the background. This was easy enough to do with React Native AppState. However, it seems significantly trickier to write such a workaround for handling when the phone’s screen is turned off, at least using pure React Native.

Any ideas as to how the library could be updated to prevent these errors when the app state is changed during a zeroconf scan?

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 1
  • Comments: 21 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Awesome, @DennisSnijder! That worked for me as well. This is the hook-based variation that I came up with:

const [appState, setAppState] = useState(AppState.currentState);
const previousAppState = usePrevious(appState);
const [rnZeroconf, setZeroConf] = useState<RNZeroconf | null>(null);

const handleAppStateChange = (state: AppStateStatus) => {
    setAppState(state);
};

useEffect(() => {
    AppState.addEventListener('change', handleAppStateChange);
    return () => AppState.removeEventListener('change', handleAppStateChange);
}, []);

useEffect(() => {
    if (appState === 'active' && previousAppState === 'active') {
        return;
    }

    if (appState === 'active') {
        rnZeroconf?.addDeviceListeners();
    }

    rnZeroconf?.removeDeviceListeners();
}, [appState, previousAppState, rnZeroconf]);

with helper:

function usePrevious<T>(value: T) {
  const ref = useRef<T>();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

@balthazar @jdpigeon I found a fix/solution to this, you can listen for the “AppState” and remove the listener when the app becomes inactive and re-add them when the app becomes active again.

Here’s an example:

import {AppState} from 'react-native';

AppState.addEventListener('change', this.handleAppStateChange.bind(this));
 private appState: string = 'active';

  private handleAppStateChange(nextAppState: string): void {
    if (this.appState === 'active' && nextAppState === 'active') {
      return;
    }

    this.appState = nextAppState;

    if (nextAppState === 'active') {
      return this.zeroConf.addDeviceListeners();
    }

    return this.zeroConf.removeDeviceListeners();
  }

The first line in the function prevents the listener to be added twice (This triggers an error as-well). Hope this helps 😄

@pellepersson Landed a similar change in the latest 0.8.0 version. @SiteFlo and @jamsesso did the same thing in their forks too, and might be interested.

I am having the same issue as described here and I do believe it is related to #12 as well.

I am doing a new scan on network change and/or when the app state is changed to “active”. I can trigger it by being in the app, double tapping the home button and then choose the app again. If I do this many times quite fast the error eventually appears and the service that is supposed to be resolved is set to nil for some reason.

At the moment I have added a check: if (service != nil) before doing anything with the service and everything seem to work fine. Of course that is not really solving the problem. Do you guys have any suggestions on why the service is nil?

@jdpigeon - why do you think it is related to the “socket is not connected” issue that lots of people got with iOS 10?