Skip to content

RNSimpleOpenvpn.connect call triggers event duplications in addVpnStateListener on IOS #80

@hamsterhomka

Description

@hamsterhomka

Bug description:
On iOS, each time RNSimpleOpenvpn.connect() is called, it duplicates the next event received by addVpnStateListener, causing events to stack indefinitely.

To Reproduce:

import { useEffect } from 'react';
import { Button, Platform, View } from 'react-native';
import RNSimpleOpenvpn, { addVpnStateListener, removeVpnStateListener } from 'react-native-simple-openvpn';


const vpnConfig = `your ovpn config`;


const isIPhone = Platform.OS === 'ios';

const App = () => {
  useEffect(() => {
    async function observeVpn() {
      if (isIPhone) {
        console.log('is iphone');
        await RNSimpleOpenvpn.observeState();
      }

      // The event gets duplicated after each RNSimpleOpenvpn.connect() call.
      addVpnStateListener((event) => {
        console.log(event, 'event');
      });
    }

    observeVpn();

    return async () => {
      if (isIPhone) {
        await RNSimpleOpenvpn.stopObserveState();
      }

      removeVpnStateListener();
    };
  });

  async function startOvpn() {
    console.log('startOvpn');

    try {
      await RNSimpleOpenvpn.connect({
        notificationTitle: 'title',
        ovpnString: vpnConfig,
        providerBundleIdentifier: 'com.hamsterhomka.yourapp.networkextension',
        localizedDescription: 'hello world',
      });

      console.log('startOvpn success');
    } catch (error) {
      console.log('error');
      console.error(error);
    }
  }

  async function stopOvpn() {
    try {
      await RNSimpleOpenvpn.disconnect();
    } catch (error) {
      console.error(error);
    }
  }

  return (
    <View style={ {paddingTop: 200} }>
      {/* Calling startOvpn causes event duplication in addVpnStateListener when an event is fired. */}
      <Button title="open" onPress={ startOvpn } />
      <Button title="stop" onPress={ stopOvpn } />
    </View>
  );
};

export default App;

It seems the issue lies in the iOS native code, as both addVpnStateListener and RNSimpleOpenvpn.observeState() are only called once.

Only closing and reopening the app resets the number of fired events, indicating that the issue lies in the native code rather than the JavaScript code. In the development build, the "Reload" button doesn't reset the number of fired events.

Expected behavior:
Events in addVpnStateListener should not be duplicated. The callback should be invoked only once per listener trigger.

Screenshots/Videos:

Image

Environment:

  • OS: IOS
  • OS version: 18.0.1
  • react-native version: 0.74.5
  • react-native-simple-openvpn version: 2.1.2

On Android everything works just fine.

Anyone with an idea on how to fix this issue, please help!
Thank you in advance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions