コード例 #1
0
        public void TestLotsOfMessages()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            WebSocketEchoServer server = new WebSocketEchoServer(pool);

            try
            {
                server.Start();

                BlockingCollection <object> blockingCollection = new BlockingCollection <object>();

                ClientSockNetChannel client = (ClientSockNetChannel)SockNetClient.Create(server.Endpoint, ClientSockNetChannel.DefaultNoDelay, ClientSockNetChannel.DefaultTtl, pool)
                                              .AddModule(new WebSocketClientSockNetChannelModule("/", "localhost", (ISockNetChannel sockNetClient) => { blockingCollection.Add(true); }));

                client.Connect().WaitForValue(TimeSpan.FromSeconds(5));

                object currentObject;

                Assert.IsTrue(blockingCollection.TryTake(out currentObject, DEFAULT_ASYNC_TIMEOUT));
                Assert.IsTrue((bool)currentObject);

                client.Pipe.AddIncomingLast <WebSocketFrame>((ISockNetChannel sockNetClient, ref WebSocketFrame data) => { blockingCollection.Add(data); });

                byte[] randomData = new byte[2000];
                new Random(GetHashCode() ^ DateTime.Now.Millisecond).NextBytes(randomData);

                for (int i = 0; i < 1000; i++)
                {
                    client.Send(WebSocketFrame.CreateBinaryFrame(randomData, false));
                }

                int receivedMessages = 0;

                for (int i = 0; i < 1000; i++)
                {
                    if (receivedMessages < 1000 && blockingCollection.TryTake(out currentObject, DEFAULT_ASYNC_TIMEOUT))
                    {
                        receivedMessages++;
                    }
                    else
                    {
                        break;
                    }
                }

                Assert.AreEqual(1000, receivedMessages);

                client.Disconnect().WaitForValue(TimeSpan.FromSeconds(5));
            }
            finally
            {
                server.Stop();
            }
        }
コード例 #2
0
        public void TestContinuationEchoWithMask()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            WebSocketEchoServer server = new WebSocketEchoServer(pool);

            try
            {
                server.Start(false, true);

                BlockingCollection <object> blockingCollection = new BlockingCollection <object>();

                ClientSockNetChannel client = (ClientSockNetChannel)SockNetClient.Create(server.Endpoint, ClientSockNetChannel.DefaultNoDelay, ClientSockNetChannel.DefaultTtl, pool)
                                              .AddModule(new WebSocketClientSockNetChannelModule("/", "localhost", (ISockNetChannel sockNetClient) => { blockingCollection.Add(true); }));

                client.Connect().WaitForValue(TimeSpan.FromSeconds(5));

                object currentObject;

                Assert.IsTrue(blockingCollection.TryTake(out currentObject, DEFAULT_ASYNC_TIMEOUT));
                Assert.IsTrue((bool)currentObject);

                client.Pipe.AddIncomingLast <WebSocketFrame>((ISockNetChannel sockNetClient, ref WebSocketFrame data) => { blockingCollection.Add(data); });

                Random rand = new Random(this.GetHashCode() ^ DateTime.Now.Millisecond);

                byte[] rawData = new byte[rand.Next(5000, 10000)];
                rand.NextBytes(rawData);

                client.Send(WebSocketFrame.CreateBinaryFrame(rawData, true));

                Assert.IsTrue(blockingCollection.TryTake(out currentObject, DEFAULT_ASYNC_TIMEOUT));
                Assert.IsTrue(currentObject is WebSocketFrame);

                AreArraysEqual(rawData, ((WebSocketFrame)currentObject).Data);

                client.Disconnect().WaitForValue(TimeSpan.FromSeconds(5));
            }
            finally
            {
                server.Stop();
            }
        }
コード例 #3
0
            /// <summary>
            /// Updates the local continuation.
            /// </summary>
            /// <param name="frame"></param>
            private void UpdateContinuation(ref WebSocketFrame continuationFrame, WebSocketFrame frame)
            {
                if (continuationFrame == null)
                {
                    continuationFrame = frame;  // set initial frame
                }
                else
                {
                    byte[] frameData = new byte[continuationFrame.Data.Length + frame.Data.Length];
                    Buffer.BlockCopy(continuationFrame.Data, 0, frameData, 0, continuationFrame.Data.Length);
                    Buffer.BlockCopy(frame.Data, 0, frameData, continuationFrame.Data.Length, frame.Data.Length);

                    switch (continuationFrame.Operation)
                    {
                    case WebSocketFrame.WebSocketFrameOperation.BinaryFrame:
                        continuationFrame = WebSocketFrame.CreateBinaryFrame(frameData, false, false);
                        break;

                    case WebSocketFrame.WebSocketFrameOperation.TextFrame:
                        continuationFrame = WebSocketFrame.CreateTextFrame(frameData, false, false);
                        break;
                    }
                }
            }
コード例 #4
0
        public void TestSmallMessagesInParallel()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            Random random = new Random(this.GetHashCode() ^ DateTime.Now.Millisecond);

            WebSocketEchoServer server = new WebSocketEchoServer(pool);

            try
            {
                server.Start();

                BlockingCollection <object> blockingCollection = new BlockingCollection <object>();

                ClientSockNetChannel client = (ClientSockNetChannel)SockNetClient.Create(server.Endpoint, ClientSockNetChannel.DefaultNoDelay, ClientSockNetChannel.DefaultTtl, pool)
                                              .AddModule(new WebSocketClientSockNetChannelModule("/", "localhost", (ISockNetChannel sockNetClient) => { blockingCollection.Add(true); }));

                client.Connect().WaitForValue(TimeSpan.FromSeconds(5));

                object currentObject;

                Assert.IsTrue(blockingCollection.TryTake(out currentObject, DEFAULT_ASYNC_TIMEOUT));
                Assert.IsTrue((bool)currentObject);

                client.Pipe.AddIncomingLast <WebSocketFrame>((ISockNetChannel sockNetClient, ref WebSocketFrame data) => { blockingCollection.Add(data); });

                int numberOfMessages = 100;

                byte[][] expectedResults = new byte[numberOfMessages][];

                for (int i = 0; i < numberOfMessages; i++)
                {
                    ThreadPool.QueueUserWorkItem((object state) =>
                    {
                        int index = (int)state;

                        byte[] messageData = new byte[random.Next(50, 100)];
                        random.NextBytes(messageData);
                        messageData[0] = (byte)(index >> 0);
                        messageData[1] = (byte)(index >> 8);
                        messageData[2] = (byte)(index >> 16);
                        messageData[3] = (byte)(index >> 24);

                        expectedResults[index] = messageData;

                        client.Send(WebSocketFrame.CreateBinaryFrame(messageData));

                        // simulate GC
                        if (index % Math.Max(numberOfMessages / 10, 1) == 0)
                        {
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                        }
                    }, i);
                }

                for (int i = 0; i < numberOfMessages; i++)
                {
                    Assert.IsTrue(blockingCollection.TryTake(out currentObject, DEFAULT_ASYNC_TIMEOUT));
                    Assert.IsTrue(currentObject is WebSocketFrame);

                    // simulate GC
                    if (i % Math.Max(numberOfMessages / 10, 1) == 0)
                    {
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }

                    byte[] incomingData = ((WebSocketFrame)currentObject).Data;
                    int    index        = 0;

                    index |= incomingData[0] << 0;
                    index |= incomingData[1] << 8;
                    index |= incomingData[2] << 16;
                    index |= incomingData[3] << 24;

                    Console.WriteLine(index);

                    AreArraysEqual(expectedResults[index], incomingData);
                }

                client.Disconnect().WaitForValue(TimeSpan.FromSeconds(5));
            }
            finally
            {
                server.Stop();
            }
        }
コード例 #5
0
            public void Start(bool isTls = false, bool doContinuations = false)
            {
                server = SockNetServer.Create(GetLocalIpAddress(), 0, ServerSockNetChannel.DefaultBacklog, pool);

                try
                {
                    server.AddModule(new WebSocketServerSockNetChannelModule("/", "localhost"));

                    if (isTls)
                    {
                        byte[] rawCert = CertificateUtil.CreateSelfSignCertificatePfx("CN=\"test\"; C=\"USA\"", DateTime.Today.AddDays(-10), DateTime.Today.AddDays(+10));

                        server.BindWithTLS(new X509Certificate2(rawCert),
                                           (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => { return(true); }).WaitForValue(TimeSpan.FromSeconds(5));
                    }
                    else
                    {
                        server.Bind().WaitForValue(TimeSpan.FromSeconds(5));
                    }

                    Assert.IsTrue(server.IsActive);

                    server.Pipe.AddIncomingLast <WebSocketFrame>((ISockNetChannel channel, ref WebSocketFrame data) =>
                    {
                        if (doContinuations)
                        {
                            int perFrameSize = data.Data.Length / 3;

                            for (int i = 0; i < 3; i++)
                            {
                                bool isDone = false;
                                byte[] rawData;

                                if (i + 1 < 3)
                                {
                                    rawData = new byte[perFrameSize];
                                    isDone  = false;
                                }
                                else
                                {
                                    rawData = new byte[data.Data.Length - (perFrameSize * 2)];
                                    isDone  = true;
                                }

                                Buffer.BlockCopy(data.Data, i * perFrameSize, rawData, 0, rawData.Length);

                                if (data.Operation == WebSocketFrame.WebSocketFrameOperation.BinaryFrame)
                                {
                                    channel.Send(WebSocketFrame.CreateBinaryFrame(rawData, true, i != 0, isDone));
                                }
                                else
                                {
                                    channel.Send(WebSocketFrame.CreateTextFrame(rawData, true, i != 0, isDone));
                                }
                            }
                        }
                        else
                        {
                            channel.Send(data);
                        }
                    });
                }
                catch (Exception)
                {
                    Stop();
                }
            }
コード例 #6
0
        public void TestLargeMessage()
        {
            ObjectPool <byte[]> pool = new ObjectPool <byte[]>(() => { return(new byte[1024]); });

            DummySockNetChannel channel = new DummySockNetChannel()
            {
                State      = null,
                IsActive   = true,
                BufferPool = pool
            };

            channel.Pipe = new SockNetChannelPipe(channel);

            WebSocketClientSockNetChannelModule module = new WebSocketClientSockNetChannelModule("/test", "test", null);

            channel.AddModule(module);
            channel.Connect();

            object sent = null;

            channel.outgoing.TryTake(out sent, 5000);
            Assert.IsTrue(sent is HttpRequest);

            HttpResponse handshakeResponse = null;

            using (HttpRequest request = (HttpRequest)sent)
            {
                handshakeResponse = new HttpResponse(null)
                {
                    Code = "200", Reason = "OK", Version = "HTTP/1.1"
                };
                handshakeResponse.Header[WebSocketUtil.WebSocketAcceptHeader] = WebSocketUtil.GenerateAccept(request.Header[WebSocketUtil.WebSocketKeyHeader]);
            }

            object receiveResponse = handshakeResponse;

            channel.Receive(ref receiveResponse);

            Random random = new Random(this.GetHashCode() ^ (int)DateTime.Now.Subtract(new DateTime(2000, 1, 1)).TotalMilliseconds);

            for (int n = 0; n < 100; n++)
            {
                byte[] data = new byte[random.Next(50000, 150000)];
                random.NextBytes(data);

                WebSocketFrame frame = WebSocketFrame.CreateBinaryFrame(data, false);
                using (ChunkedBuffer buffer = ToBuffer(frame))
                {
                    receiveResponse = buffer;
                    channel.Receive(ref receiveResponse);

                    Assert.IsTrue(receiveResponse is WebSocketFrame);
                    Assert.AreEqual(data.Length, ((WebSocketFrame)receiveResponse).Data.Length);
                    for (int i = 0; i < data.Length; i++)
                    {
                        Assert.AreEqual(data[i], ((WebSocketFrame)receiveResponse).Data[i]);
                    }
                    buffer.Close();
                }
            }

            Console.WriteLine("Pool stats: " + pool.ObjectsInPool + "/" + pool.TotalNumberOfObjects);
        }