/// <summary> /// Wait for and receive a message /// </summary> /// <returns>Decoded message. </returns> public async Task <object> ReceiveMessageAsync(CancellationToken CancelTaken = default) { try { var buffer = new ArraySegment <byte>(new byte[MessageBufferSize]); // Get the next message var rc = await Socket.ReceiveAsync(buffer, CancelTaken == default?CancellationToken.None : CancelTaken); if (rc.MessageType == WebSocketMessageType.Text) { // trim the incomming message and extract a string var messageString = Encoding.UTF8.GetString(buffer.Take(rc.Count).ToArray()); // see if the decoder can decode the message if (!ResponseDecoder.TryUnserialise(messageString, out object message)) { throw new Exception($"Invalid JSON or unknown response received: {messageString}"); } if (message == null) { throw new Exception("Internal error: Unexpected null"); } return(message); } } catch (WebSocketException ex) when(ex.InnerException is SocketException) { // closed connection and create new object Socket.Dispose(); Socket = new ClientWebSocket(); } catch (Exception ex) when(ex.InnerException is OperationCanceledException || ex is OperationCanceledException) { // Cancelled by the application but we want to keep connection up until explicitly socket is closed by the overlaying application. // throw an exception to the caller await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by the cancelled task.", CancellationToken.None); Socket.Dispose(); Socket = new ClientWebSocket(); await ConnectAsync(); throw; } catch (Exception ex) { throw new Exception(ex.Message + " StackTrace:" + ex.StackTrace); } return(null); }
public void TestDecodeResponse() { object result = null; var mockDecoder = new Mock <IDecoder <IByteBuffer> >(); mockDecoder.Setup(i => i.DecodeResponse(It.IsAny <IByteBuffer>())) .Returns <IByteBuffer>(i => { i.ReadBytes(1); i.MarkReaderIndex(); return(new Response()); }); var context = new Mock <IChannelHandlerContext>(); context.Setup(i => i.FireChannelRead(It.IsAny <object>())) .Callback <object>(i => result = i); var reqDecoder = new ResponseDecoder(mockDecoder.Object); reqDecoder.ChannelRead(context.Object, Unpooled.WrappedBuffer(new byte[] { 3 })); Assert.NotNull(result); Assert.IsType <Response>(result); }