pusher / pusher-websocket-unity

Pusher Channels Unity Client Library
MIT License
27 stars 20 forks source link

Running on main thread issues when using _channel.Bind() in Pusher SDK #59

Open miladxandi opened 3 months ago

miladxandi commented 3 months ago

That`s my code which we changed a lot because of an error!

This is "LoadingRoom.cs":

    private string baseUrl = "https://example.com/";
    void Start()
    {
        try
        {
            StartCoroutine(InitialisePusher());
        }
        catch (Exception e)
        {
            Debug.Log(e.Message);
        }
    }

Then we initialize the pusher & sign in the user, then subscribe it to a channel and bind for an event in the code:

    private IEnumerator InitialisePusher()
    {
        if (_pusher == null && (APP_KEY != "APP_KEY") && (APP_CLUSTER != "APP_CLUSTER"))
        {
             _pusher = new Pusher(APP_KEY, new PusherOptions()
            {
                Cluster = APP_CLUSTER,
                Encrypted = true,
                Authorizer = new HttpAuthorizer(baseUrl + "api/auth/authorizer")
                {
                    AuthenticationHeader = AuthenticationHeaderValue.Parse("Bearer " + PlayerPrefs.GetString("token"))
                },
            });

            _pusher.Error += OnPusherOnError;
            _pusher.ConnectionStateChanged += PusherOnConnectionStateChanged;
            _pusher.Connected += PusherOnConnected;

            // Use yield return to wait for asynchronous operation (SubscribeAsync)
            yield return new WaitUntil(() =>
            {
                _channel = _pusher.SubscribeAsync("private-" + PlayerPrefs.GetString("Channel")).Result;
                if (_channel != null)
                {
                    return true;
                }

                return false;
            });

            _pusher.Subscribed += OnChannelOnSubscribed;
            _pusher.ConnectAsync();
        }
        else
        {
             Debug.Log("APP_KEY and APP_CLUSTER must be correctly set. Find how to set it at https://dashboard.pusher.com");
        }
    }
    private void PusherOnConnected(object sender)
    {
        _channel.Bind("connected", (PusherEvent data) =>
        {
            StartCoroutine(GetList()); //The bug happens here when we want to run the StartCoroutine() method in here because it will run on a different thread than the main thread!
        });
    }

But I got this error:

Error: Error invoking the action for the emitted event connected:
IsObjectMonoBehaviour can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

Because we want to wait for the "GetList" method which that`s an IEnumerator; to be completed, we cannot run it on the Start or Awake methods.