public async Task SimpleNamedPipes() { Func <MemoryStream> memoryStreamFactory = () => new MemoryStream(); string pipeName = Guid.NewGuid().ToString(); using (var clientPipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous)) using (var serverPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Task clientConnectTask = clientPipe.ConnectAsync(); Task serverConnectTask = serverPipe.WaitForConnectionAsync(); Task.WaitAll(clientConnectTask, serverConnectTask); var webSocketClient = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, clientPipe, TimeSpan.Zero, null, false, true, null); var webSocketServer = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, serverPipe, TimeSpan.Zero, null, false, false, null); CancellationTokenSource tokenSource = new CancellationTokenSource(); var clientReceiveTask = Task.Run <string[]>(() => ReceiveClient(webSocketClient, tokenSource.Token)); var serverReceiveTask = Task.Run(() => ReceiveServer(webSocketServer, tokenSource.Token)); ArraySegment <byte> message1 = GetBuffer("Hi"); ArraySegment <byte> message2 = GetBuffer("There"); await webSocketClient.SendAsync(message1, WebSocketMessageType.Binary, true, tokenSource.Token); await webSocketClient.SendAsync(message2, WebSocketMessageType.Binary, true, tokenSource.Token); await webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, null, tokenSource.Token); string[] replies = await clientReceiveTask; foreach (string reply in replies) { Console.WriteLine(reply); } } }
public async Task SimpleSend() { Func <MemoryStream> memoryStreamFactory = () => new MemoryStream(); var theInternet = new TheInternet(); var webSocketClient = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, theInternet.ClientNetworkStream, TimeSpan.Zero, null, false, true, null); var webSocketServer = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, theInternet.ServerNetworkStream, TimeSpan.Zero, null, false, false, null); CancellationTokenSource tokenSource = new CancellationTokenSource(); var clientReceiveTask = Task.Run <string[]>(() => ReceiveClient(webSocketClient, tokenSource.Token)); var serverReceiveTask = Task.Run(() => ReceiveServer(webSocketServer, tokenSource.Token)); ArraySegment <byte> message1 = GetBuffer("Hi"); ArraySegment <byte> message2 = GetBuffer("There"); await webSocketClient.SendAsync(message1, WebSocketMessageType.Binary, true, tokenSource.Token); await webSocketClient.SendAsync(message2, WebSocketMessageType.Binary, true, tokenSource.Token); await webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, null, tokenSource.Token); string[] replies = await clientReceiveTask; foreach (string reply in replies) { Console.WriteLine(reply); } }
/// <summary> /// Initialises a new instance of the PingPongManager to facilitate ping pong WebSocket messages. /// If you are manually creating an instance of this class then it is advisable to set keepAliveInterval to /// TimeSpan.Zero when you create the WebSocket instance (using a factory) otherwise you may be automatically /// be sending duplicate Ping messages (see keepAliveInterval below) /// </summary> /// <param name="webSocket">The web socket used to listen to ping messages and send pong messages</param> /// <param name="keepAliveInterval">The time between automatically sending ping messages. /// Set this to TimeSpan.Zero if you with to manually control sending ping messages. /// </param> /// <param name="cancellationToken">The token used to cancel a pending ping send AND the automatic sending of ping messages /// if keepAliveInterval is positive</param> public PingPongManager(Guid guid, WebSocket webSocket, TimeSpan keepAliveInterval, CancellationToken cancellationToken) { var webSocketImpl = webSocket as WebSocketImplementation; _webSocket = webSocketImpl; if (_webSocket == null) { throw new InvalidCastException( "Cannot cast WebSocket to an instance of WebSocketImplementation. Please use the web socket factories to create a web socket"); } _guid = guid; _keepAliveInterval = keepAliveInterval; _cancellationToken = cancellationToken; webSocketImpl.Pong += WebSocketImpl_Pong; _stopwatch = Stopwatch.StartNew(); if (keepAliveInterval == TimeSpan.Zero) { _pingTask = Task.FromResult(0); } else { _pingTask = Task.Run(PingForever, cancellationToken); } }
// get connection info in case it's needed (IP etc.) // (we should never pass the TcpClient to the outside) public string GetClientAddress(int connectionId) { // find the connection if (clients.TryGetValue(connectionId, out WebSocket client)) { WebSocketImplementation wsClient = client as WebSocketImplementation; return(wsClient.Context.Client.Client.RemoteEndPoint.ToString()); } return(null); }
public async Task CanCancelSend() { Func <MemoryStream> memoryStreamFactory = () => new MemoryStream(); var theInternet = new TheInternet(); var webSocketClient = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, theInternet.ClientNetworkStream, TimeSpan.Zero, null, false, true, null); CancellationTokenSource tokenSource = new CancellationTokenSource(); ArraySegment <byte> buffer = new ArraySegment <byte>(new byte[10]); tokenSource.Cancel(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => webSocketClient.SendAsync(buffer, WebSocketMessageType.Binary, true, tokenSource.Token)); }
/// <summary> /// Accept web socket with options specified /// Call ReadHttpHeaderFromStreamAsync first to get WebSocketHttpContext /// </summary> /// <param name="context">The http context used to initiate this web socket request</param> /// <param name="options">The web socket options</param> /// <param name="token">The optional cancellation token</param> /// <returns>A connected web socket</returns> public async Task <WebSocket> AcceptWebSocketAsync(WebSocketHttpContext context, WebSocketServerOptions options, CancellationToken token = default(CancellationToken)) { var guid = Guid.NewGuid(); Events.Log.AcceptWebSocketStarted(guid); await PerformHandshakeAsync(guid, context.HttpHeader, options.SubProtocol, context.Stream, token); Events.Log.ServerHandshakeSuccess(guid); string secWebSocketExtensions = null; var websocket = new WebSocketImplementation(guid, _bufferFactory, context.Stream, options.KeepAliveInterval, secWebSocketExtensions, options.IncludeExceptionInCloseResponse, false, options.SubProtocol) { TcpClient = context.Client }; return(websocket); }
public async Task ReceiveBufferTooSmallToFitWebsocketFrameTest() { Func <MemoryStream> memoryStreamFactory = () => new MemoryStream(); string pipeName = Guid.NewGuid().ToString(); using (var clientPipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous)) using (var serverPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Task clientConnectTask = clientPipe.ConnectAsync(); Task serverConnectTask = serverPipe.WaitForConnectionAsync(); Task.WaitAll(clientConnectTask, serverConnectTask); var webSocketClient = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, clientPipe, TimeSpan.Zero, null, false, true, null); var webSocketServer = new WebSocketImplementation(Guid.NewGuid(), memoryStreamFactory, serverPipe, TimeSpan.Zero, null, false, false, null); CancellationTokenSource tokenSource = new CancellationTokenSource(); var clientReceiveTask = Task.Run <string[]>(() => ReceiveClient(webSocketClient, tokenSource.Token)); // here we use a server with a buffer size of 10 which is smaller than the websocket frame var serverReceiveTask = Task.Run(() => ReceiveServer(webSocketServer, 10, tokenSource.Token)); ArraySegment <byte> message1 = GetBuffer("This is a test message"); await webSocketClient.SendAsync(message1, WebSocketMessageType.Binary, true, tokenSource.Token); await webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, null, tokenSource.Token); await serverReceiveTask; string[] replies = await clientReceiveTask; foreach (string reply in replies) { Console.WriteLine(reply); } Assert.Equal(3, replies.Length); Assert.Equal("Server: This is ", replies[0]); Assert.Equal("Server: a test m", replies[1]); Assert.Equal("Server: essage", replies[2]); } }