public async Task ConnectionCanReadAndWrite() { var transportContext = new TestLibuvTransportContext(); await using var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0)); await transport.BindAsync(); var endpoint = (IPEndPoint)transport.EndPoint; async Task EchoServerAsync() { while (true) { await using var connection = await transport.AcceptAsync(); if (connection == null) { break; } while (true) { var result = await connection.Transport.Input.ReadAsync(); if (result.IsCompleted) { break; } await connection.Transport.Output.WriteAsync(result.Buffer.ToArray()); connection.Transport.Input.AdvanceTo(result.Buffer.End); } } } var serverTask = EchoServerAsync(); using (var socket = TestConnection.CreateConnectedLoopbackSocket(endpoint.Port)) { var data = Encoding.ASCII.GetBytes("Hello World"); await socket.SendAsync(data, SocketFlags.None); var buffer = new byte[data.Length]; var read = 0; while (read < data.Length) { read += await socket.ReceiveAsync(buffer.AsMemory(read, buffer.Length - read), SocketFlags.None); } Assert.Equal(data, buffer); } await transport.UnbindAsync(); await serverTask.DefaultTimeout(); }
public async Task CallingAcceptAfterDisposeAsyncThrows() { var transportContext = new TestLibuvTransportContext(); var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0)); await transport.BindAsync(); var endpoint = (IPEndPoint)transport.EndPoint; await transport.UnbindAsync(); await transport.DisposeAsync(); await Assert.ThrowsAsync<ObjectDisposedException>(() => transport.AcceptAsync().AsTask()); }
public async Task CallingDisposeAsyncWillYieldPendingAccepts() { var transportContext = new TestLibuvTransportContext(); await using var transport = new LibuvConnectionListener(transportContext, new IPEndPoint(IPAddress.Loopback, 0)); await transport.BindAsync(); var acceptTask = transport.AcceptAsync(); await transport.UnbindAsync(); var connection = await acceptTask.DefaultTimeout(); Assert.Null(connection); }
public virtual async Task Start(MessagePump pump) { try { await m_Listener.BindAsync(); } catch (AddressInUseException) { Console.WriteLine("Listener Failed: {0}:{1} (In Use)", m_EndPoint.Address, m_EndPoint.Port); m_Listener = null; return; } catch (Exception e) { Console.WriteLine("Listener Exception:"); Console.WriteLine(e); m_Listener = null; return; } DisplayListener(); while (true) { ConnectionContext context; try { context = await m_Listener.AcceptAsync(); } catch (SocketException ex) { NetState.TraceException(ex); continue; } if (VerifySocket(context)) { _ = new NetState(context, pump); } else { Release(context); } } }
static void Main(string[] args) { Console.WriteLine("Main: {0}", Thread.CurrentThread.ManagedThreadId); // Use the factory LibuvTransportContext transport = new LibuvTransportContext { Options = new LibuvTransportOptions(), AppLifetime = new ApplicationLifetime(null), Log = new LibuvTrace(LoggerFactory.Create(builder => { builder.AddConsole(); }).CreateLogger("core")) }; LibuvThread uvThread = new LibuvThread(libUv, transport); uvThread.StartAsync().Wait(); Task.Run(async() => { Console.WriteLine("NIO: {0}", Thread.CurrentThread.ManagedThreadId); LibuvConnectionListener listener = new LibuvConnectionListener(libUv, transport, new IPEndPoint(IPAddress.Parse("0.0.0.0"), 2593)); Console.WriteLine("Binding... ({0})", Thread.CurrentThread.ManagedThreadId); await listener.BindAsync(); Console.WriteLine("Listening... ({0})", Thread.CurrentThread.ManagedThreadId); ConnectionContext connectionContext = await listener.AcceptAsync(); Console.WriteLine("Accepted Connection from {0}", connectionContext.RemoteEndPoint); PipeReader reader = connectionContext.Transport.Input; while (true) { ReadResult readResult = await reader.ReadAsync(); int packetId = readResult.Buffer.FirstSpan[0]; Console.WriteLine($"[0x{packetId:X}] Processing Packet"); int length = PacketLengths[packetId]; int bodyLength = length - 1; int bodyStart = 1; if (length == 0) { length = BinaryPrimitives.ReadUInt16BigEndian(readResult.Buffer.FirstSpan.Slice(1, 2)); bodyLength = length - 3; bodyStart = 3; } else if (length == 0xFFFF) { Console.WriteLine($"[0x{packetId:X}] Unknown Packet"); throw new Exception($"[0x{packetId:X}] Unknown Packet"); } Console.WriteLine($"[0x{packetId:X}] Found length {length}"); Console.WriteLine($"Packet Data: {ByteArrayToString(readResult.Buffer.FirstSpan.ToArray()):X}"); Memory <byte> mem = new Memory <byte>(readResult.Buffer.FirstSpan.Slice(bodyStart, bodyLength).ToArray()); Console.WriteLine($"[0x{packetId:X}] Buffer length {mem.Length}"); _ = uvThread.PostAsync((Tuple <ConnectionContext, Memory <byte> > t) => { // stuff var(conn, mem) = t; // Do stuff wtih memOwner.Memory.Span; Console.WriteLine($"Packet ID: 0x{packetId:X} - Length: {length} - Data: 0x{ByteArrayToString(mem.ToArray())}"); }, Tuple.Create(connectionContext, mem)); reader.AdvanceTo(readResult.Buffer.GetPosition(length)); } }); // Manually putting something on the queue from another thread (or the main thread) uvThread.PostAsync <object>(_ => { Console.WriteLine("Game: {0}", Thread.CurrentThread.ManagedThreadId); }, null); // Send an Initialization Request for Timers /* * uvThread.PostAsync<object>(_ => * { * UvTimerHandle timerHandle = new UvTimerHandle(null); * timerHandle.Init(uvThread.Loop, (callback, handle) => * { * Console.WriteLine("Closed ({0})", Thread.CurrentThread.ManagedThreadId); * }); * Console.WriteLine("Timer Stuff {0}", Thread.CurrentThread.ManagedThreadId); * int count = 10; * void cb2(UvTimerHandle handle) * { * Console.WriteLine("Called!2 {0} ({1})", DateTime.Now, Thread.CurrentThread.ManagedThreadId); * timerHandle.Start(cb2, 2000, 0); * } * void cb1(UvTimerHandle handle) * { * Console.WriteLine("Called!1 {0} ({1})", DateTime.Now, Thread.CurrentThread.ManagedThreadId); * count--; * if (count < 0) * timerHandle.Start(cb2, 2000, 0); * else * timerHandle.Start(cb1, 1000, 0); * } * timerHandle.Start(cb1, 1000, 0); * }, null); */ Console.ReadLine(); }