Esempio n. 1
0
        private void RaiseStatusChanged()
        {
            var tmp = statusChanged;

            if (tmp != null)
            {
                eventScheduler.Schedule(() => tmp(this, new EventArgs()));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// The pump for received messages.
        /// </summary>
        /// <param name="uri">
        /// The uri.
        /// </param>
        /// <param name="cancellation">
        /// The cancellation token source.
        /// </param>
        /// <returns>
        /// The observable stream of messages.
        /// </returns>
        private static IObservableSocket CreateObservableSocket(Uri uri, CancellationTokenSource cancellation)
        {
            var status               = new ReplaySubject <ConnectionStatus>(1);
            var socket               = new WebSocket4Net.WebSocket(uri.ToString());
            var connected            = new TaskCompletionSource <int>();
            var dispatcher           = new ConcurrentExclusiveSchedulerPair();
            var sendScheduler        = new TaskPoolScheduler(new TaskFactory(dispatcher.ExclusiveScheduler));
            var receiveScheduler     = new TaskPoolScheduler(new TaskFactory(dispatcher.ConcurrentScheduler));
            Func <string, Task> send = message =>
            {
                var tcs = new TaskCompletionSource <int>();
                sendScheduler.Schedule(
                    () =>
                {
                    try
                    {
                        if (socket.State != WebSocket4Net.WebSocketState.Open)
                        {
                            socket.Open();
                        }

                        socket.Send(message);
                        tcs.SetResult(0);
                    }
                    catch (Exception e)
                    {
                        tcs.SetException(e);
                    }
                });
                ;

                return(tcs.Task);
            };

            socket.Open();
            var incoming = Observable.Create <string>(
                observer =>
            {
                status.OnNext(ConnectionStatus.Connecting);
                var completed = false;
                EventHandler <WebSocket4Net.MessageReceivedEventArgs> onMessage    = (sender, args) => observer.OnNext(args.Message);
                EventHandler <ws::SuperSocket.ClientEngine.ErrorEventArgs> onError = (sender, args) =>
                {
                    observer.OnError(args.Exception);
                    completed = true;
                    cancellation.Cancel();
                };
                EventHandler onClosed = (sender, args) => cancellation.Cancel();

                socket.MessageReceived += onMessage;
                socket.Error           += onError;
                socket.Closed          += onClosed;
                socket.Opened          += (sender, args) => connected.TrySetResult(0);
                cancellation.Token.Register(
                    () =>
                {
                    if (!completed)
                    {
                        observer.OnCompleted();
                    }

                    socket.MessageReceived -= onMessage;
                    socket.Error           -= onError;
                    socket.Closed          -= onClosed;
                    try
                    {
                        socket.Close();
                    }
                    catch
                    {
                        // Ignore errors closing the socket.
                    }

                    dispatcher.Complete();
                });

                return(Disposable.Create(cancellation.Cancel));
            }).SubscribeOn(receiveScheduler).Publish().RefCount();

            return(new ObservableSocket(incoming, send, status, connected.Task));
        }