public IObservable<Unit> SendMessage(Socket connectedSocket, SocketAsyncEventArgs socketEventArgs, IScheduler scheduler, string message)
        {
            if (connectedSocket == null)
                throw new ArgumentNullException("connectedSocket");

            if (socketEventArgs == null)
                throw new ArgumentNullException("socketEventArgs");

            return Observable.Create<Unit>(observer =>
            {
                var disposable = new CompositeDisposable();
                var buffer = Encoding.UTF8.GetBytes(message);

                var disposableCompletedSubscription = socketEventArgs.CompletedObservable().ObserveOn(scheduler).Subscribe(_ =>
                {
                    SendNotificationToObserver(observer, socketEventArgs);
                });

                var disposableActions = scheduler.Schedule(() =>
                {
                    socketEventArgs.SetBuffer(buffer, 0, buffer.Length);
                    if (!connectedSocket.SendAsync(socketEventArgs))
                    {
                        SendNotificationToObserver(observer, socketEventArgs);
                    }
                });

                disposable.Add(disposableCompletedSubscription);
                disposable.Add(disposableActions);

                return disposable;
            });
        }
        public IObservable<string> Receive(Socket connectedSocket, SocketAsyncEventArgs socketEventArgs, IScheduler scheduler, byte[] buffer)
        {
            if (connectedSocket == null)
                throw new ArgumentNullException("connectedSocket");

            if (socketEventArgs == null)
                throw new ArgumentNullException("socketEventArgs");

            return Observable.Create<string>(observer =>
            {
                var disposable = new CompositeDisposable();

                var disposableEventSubscription = socketEventArgs.CompletedObservable().ObserveOn(scheduler).Subscribe(_ =>
                {
                    SendNotificationToObserver(observer, socketEventArgs);
                });

                var disposableActions = scheduler.Schedule(() =>
                {
                    socketEventArgs.SetBuffer(buffer, 0, buffer.Length);
                    if (!connectedSocket.ReceiveAsync(socketEventArgs))
                    {
                        SendNotificationToObserver(observer, socketEventArgs);
                    }
                });

                disposable.Add(disposableEventSubscription);
                disposable.Add(disposableActions);

                return disposable;
            });
        }
        internal static IObservable <SocketAsyncEventArgs> InvokeAsync(this SocketAsyncEventArgs eventArgs, Func <SocketAsyncEventArgs, bool> invoke)
        {
            Contract.Requires(eventArgs != null);
            Contract.Requires(invoke != null);
            Contract.Ensures(Contract.Result <IObservable <SocketAsyncEventArgs> >() != null);

            var completed = eventArgs.CompletedObservable();

            var connection = completed.Connect();

            if (invoke(eventArgs))
            {
                return(completed.AsObservable());
            }
            else
            {
                connection.Dispose();

                return(eventArgs.GetResult());
            }
        }