buttplug-csharp icon indicating copy to clipboard operation
buttplug-csharp copied to clipboard

Cancelation token on ConnectAsync will kill a connection after it's returned

Open blackspherefollower opened this issue 2 years ago • 1 comments

Given the very simple WinForms example:

using System;
using System.Threading;
using System.Windows.Forms;
using Buttplug.Client;
using Buttplug.Client.Connectors.WebsocketConnector;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        ButtplugWebsocketConnector myConnector;
        ButtplugClient client = new ButtplugClient("Test Client");
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            var cts = new CancellationTokenSource();
            cts.CancelAfter(TimeSpan.FromSeconds(5));
            client.ConnectAsync(new ButtplugWebsocketConnector(new Uri("ws://127.0.0.1:12345")), cts.Token).GetAwaiter().GetResult();
        }
    }
}

The ConnectAsync() will succeed and show in intiface as connected, but will then disconnect when the token times out.

Workaround: After return, extend the timeout:

        private void button1_Click(object sender, EventArgs e)
        {
            var cts = new CancellationTokenSource();
            cts.CancelAfter(TimeSpan.FromSeconds(5));
            client.ConnectAsync(new ButtplugWebsocketConnector(new Uri("ws://127.0.0.1:12345")), cts.Token).GetAwaiter().GetResult();
            cts.CancelAfter(TimeSpan.FromDays(5));
        }

blackspherefollower avatar Nov 08 '23 10:11 blackspherefollower

The websocket uses the user provided token to shut down its event loop on cancel, which shouldn't happen. It should use a token owned by the client, not one passed in by the user.

qdot avatar Nov 08 '23 17:11 qdot