예제 #1
0
        public void AcceptAutomatic()
        {
            var address = new IPEndPoint(IPAddress.Loopback, 20154);
            var sockets = ObservableSocket.Accept(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp, address, 5);
            var connect = Observable.Defer(() => ObservableSocket.Connect(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp, address));

            var    results       = new ConcurrentBag <Socket>();
            var    errors        = new ConcurrentBag <Exception>();
            var    completed     = false;
            var    completions   = 0;
            Action addCompletion = () => Interlocked.Increment(ref completions);

            using (var wait = new ManualResetEventSlim())
                using (sockets.Subscribe(results.Add, errors.Add, wait.Set))
                    using (connect.Subscribe(results.Add, errors.Add, addCompletion))
                        using (connect.Subscribe(results.Add, errors.Add, addCompletion))
                            using (connect.Subscribe(results.Add, errors.Add, addCompletion))
                                using (connect.Subscribe(results.Add, errors.Add, addCompletion))
                                    using (connect.Subscribe(results.Add, errors.Add, addCompletion))
                                    {
                                        completed = wait.Wait(TimeSpan.FromSeconds(10));
                                    }

            Assert.AreEqual(0, errors.Count, string.Join(Environment.NewLine, errors));
            Assert.IsTrue(completed, "Timed out before completion.");
            Assert.AreEqual(10, results.Count);
            Assert.AreEqual(5, completions);
        }
예제 #2
0
        protected override void Main()
        {
            string response = UserInput(Text.PromptFormat, Instructions.EnterTheResponse);

            byte[] responseBytes = Encoding.Unicode.GetBytes(response);

            TraceLine(Instructions.PressAnyKeyToCancel);

            var serverAddress = new IPEndPoint(IPAddress.Loopback, 15007);

            IObservable <int> server =
                from socket in ObservableSocket.Accept(
                    AddressFamily.InterNetwork,
                    SocketType.Stream,
                    ProtocolType.Tcp,
                    serverAddress,
                    count: 1)
                from _ in Observable.Using(
                    () => socket,
                    _ => socket.SendUntilCompleted(responseBytes, 0, responseBytes.Length, SocketFlags.None))
                select responseBytes.Length;

            IObservable <string> client =
                from socket in ObservableSocket.Connect(
                    AddressFamily.InterNetwork,
                    SocketType.Stream,
                    ProtocolType.Tcp,
                    serverAddress)
                from message in Observable.Using(
                    () => socket,
                    _ => Observable.Using(
                        () => new MemoryStream(),
                        stream => socket
                        .ReceiveUntilCompleted(SocketFlags.None)
                        .Do(buffer => stream.Write(buffer, 0, buffer.Length))
                        .TakeLast(1)
                        .Select(__ => Encoding.Unicode.GetString(stream.ToArray()))))
                select message;

            // Ensure that the console output is thread-safe
            var gate = new object();

            server = server.Synchronize(gate);
            client = client.Synchronize(gate);

            using (server.Subscribe(ConsoleOutputFormat(Text.Server, Text.SentBytesFormat)))
                using (client.Subscribe(ConsoleOutput(Text.Client)))
                {
                    WaitForKey();
                }
        }
예제 #3
0
        protected override IDisposable SubscribeCore(IObserver <TResult> observer)
        {
            return
                ((from socket in ObservableSocket.Connect(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, Provider.EndPoint)
                  from result in
                  Observable.Create <TResult>(
                      innerObserver =>
            {
                var cancel = new CancellationDisposable();

                // disable Nagle algorithm so that observed events are received as soon as they happen
                socket.NoDelay = true;

                var subscription = Observable.Using(
                    () => new NetworkStream(socket, ownsSocket: false),
                    stream => ReadObservable(stream, cancel.Token))
                                   .Subscribe(innerObserver);

                return new CompositeDisposable(subscription, cancel);
            })
                  .Finally(socket.Close)
                  select result)
                 .Subscribe(observer));
        }