private async void CreateWebRtcTransportButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var result = await connection.InvokeAsync <dynamic>("CreateWebRtcTransport", new CreateWebRtcTransportRequest
                {
                    ForceTcp  = false,
                    Consuming = true,
                    Producing = false,
                });

                IntPtr param = Marshal.StringToHGlobalAnsi(result.ToString());

                RtclientLib.CreateSendTransport(param);
                //Marshal.FreeHGlobal(param);
                result = await connection.InvokeAsync <dynamic>("CreateWebRtcTransport", new CreateWebRtcTransportRequest
                {
                    ForceTcp  = false,
                    Consuming = false,
                    Producing = true,
                });

                RtclientLib.CreateRecvTransport(param);
                //RtclientLib.JoinRoom();
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.ToString());
            }
        }
        public MainWindow()
        {
            InitializeComponent();

            var accessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiMjkiLCJnIjoi5Yy76ZmiIiwibmJmIjoxNTg0MzQ5MDQ2LCJleHAiOjE1ODY5NDEwNDYsImlzcyI6Imlzc3VlciIsImF1ZCI6ImF1ZGllbmNlIn0._bGG1SOF9WqY8TIErRkxsh9_l_mFB_5JcGrKO1GyQ0E";

            connection = new HubConnectionBuilder()
                         .WithUrl($"https://192.168.0.124:5001/hubs/meetingHub?access_token={accessToken}")
                         .Build();

            connection.Closed += async(error) =>
            {
                await Task.Delay(new Random().Next(0, 5) * 1000);

                await connection.StartAsync();
            };

            //
            stCallBackFunStruct = new CallBackFunStruct
            {
                FunCallBackConnectServer2   = CallBackConnectServer2,
                FunCallBackConnectServer4   = CallBackConnectServer4,
                FunCallBackJoinRoom         = CallBackJoinRoom,
                FunCallBackNewConsumerReady = CallBackNewConsumerReady
            };
            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(stCallBackFunStruct));

            Marshal.StructureToPtr(stCallBackFunStruct, ptr, true);
            RtclientLib.InitializeRTC(ptr);
        }
        private async void ProcessPeerHandled(object message)
        {
            try
            {
                var result = await connection.InvokeAsync <dynamic>("EnterRoom", Guid.Empty);

                this.Dispatcher.Invoke(() =>
                {
                    var newMessage = $"{result}";
                    messagesList.Items.Add(newMessage);
                });
                result = await connection.InvokeAsync <dynamic>("GetRouterRtpCapabilities");

                this.Dispatcher.Invoke(() =>
                {
                    var newMessage = $"{result}";
                    messagesList.Items.Add(newMessage);
                });
                //load routertp
                IntPtr param = Marshal.StringToHGlobalUni(result.ToString());
                RtclientLib.LoadRtpCapabilities(param);

                //
                result = await connection.InvokeAsync <dynamic>("CreateWebRtcTransport", new CreateWebRtcTransportRequest
                {
                    ForceTcp  = false,
                    Consuming = false,
                    Producing = true,
                });

                param = Marshal.StringToHGlobalAnsi(result.ToString());
                RtclientLib.CreateSendTransport(param);

                //connectwebrtctransport

                //Marshal.FreeHGlobal(param);
                result = await connection.InvokeAsync <dynamic>("CreateWebRtcTransport", new CreateWebRtcTransportRequest
                {
                    ForceTcp  = false,
                    Consuming = true,
                    Producing = false,
                });

                param = Marshal.StringToHGlobalAnsi(result.ToString());
                RtclientLib.CreateRecvTransport(param);
                RtclientLib.JoinRoom(new WindowInteropHelper(this).Handle);
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.ToString());
            }
        }
        private async void GetRouterRtpCapabilitiesButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var result = await connection.InvokeAsync <dynamic>("GetRouterRtpCapabilities");

                IntPtr param = Marshal.StringToHGlobalAnsi(result.ToString());
                this.Dispatcher.Invoke(() =>
                {
                    var newMessage = $"{result}";
                    messagesList.Items.Add(newMessage);
                });
                RtclientLib.LoadRtpCapabilities(param);
                //Marshal.FreeHGlobal(param);
            }
            catch (Exception ex)
            {
                messagesList.Items.Add(ex.ToString());
            }
        }
        private async void ProcessNewConsumer(object message)
        {
            var param = Marshal.StringToHGlobalAnsi(message.ToString());

            RtclientLib.ConsumeStream(param, new WindowInteropHelper(this).Handle);
        }
 protected override void OnClosed(EventArgs e)
 {
     RtclientLib.Destroy();
     base.OnClosed(e);
 }