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(); } }
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(); } }
/// <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; } } }
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(); } }
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(); } }
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); }