public override bool ConnectAsync(TimeSpan timeout, TransportAsyncCallbackArgs callbackArgs) { // TODO: set socket connect timeout to timeout this.callbackArgs = callbackArgs; DnsEndPoint dnsEndPoint = new DnsEndPoint(this.transportSettings.Host, this.transportSettings.Port); SocketAsyncEventArgs connectEventArgs = new SocketAsyncEventArgs(); connectEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnectComplete); connectEventArgs.RemoteEndPoint = dnsEndPoint; connectEventArgs.UserToken = this; #if MONOANDROID // Work around for Mono issue: https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/171 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); bool connectResult = socket.ConnectAsync(connectEventArgs); #else // On Linux platform, socket connections are allowed to be initiated on the socket instance // with hostname due to multiple IP address DNS resolution possibility. // They suggest either using static Connect API or IP address directly. bool connectResult = Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, connectEventArgs); #endif if (connectResult) { return true; } else { this.Complete(connectEventArgs, true); return false; } }
public sealed override bool WriteAsync(TransportAsyncCallbackArgs args) { Fx.Assert(args.Buffer != null || args.ByteBufferList != null, "must have a buffer or buffers to write"); Fx.Assert(args.CompletedCallback != null, "must have a valid callback"); Fx.Assert(args.BytesTransfered == 0, "args.BytesTransfered != 0"); Fx.Assert(this.sendEventArgs.Args == null, "write is pending"); this.sendEventArgs.PrepareWrite(args.Count); if (args.Buffer != null) { this.sendEventArgs.SetBuffer(args.Buffer, args.Offset, args.Count); } else { ArraySegment<byte>[] buffers = new ArraySegment<byte>[args.ByteBufferList.Count]; for (int i = 0; i < buffers.Length; ++i) { buffers[i] = new ArraySegment<byte>(args.ByteBufferList[i].Buffer, args.ByteBufferList[i].Offset, args.ByteBufferList[i].Length); } this.sendEventArgs.BufferList = buffers; } this.sendEventArgs.Args = args; if (!this.socket.SendAsync(this.sendEventArgs)) { this.HandleWriteComplete(args, true); return false; } return true; }
void OnAcceptInnerTransport(TransportListener innerListener, TransportAsyncCallbackArgs innerArgs) { Fx.Assert(innerArgs.Exception == null, "Should not be called with an exception."); Fx.Assert(innerArgs.Transport != null, "Should be called with a transport."); AmqpTrace.Provider.AmqpLogOperationInformational(this, TraceOperation.Accept, innerArgs.Transport); try { // upgrade transport innerArgs.Transport = new TlsTransport(innerArgs.Transport, this.transportSettings); IAsyncResult result = innerArgs.Transport.BeginOpen( innerArgs.Transport.DefaultOpenTimeout, this.onTransportOpened, innerArgs); if (result.CompletedSynchronously) { this.HandleTransportOpened(result); return; } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } innerArgs.Transport.SafeClose(exception); } }
void HandleInnerTransportConnected(TransportAsyncCallbackArgs innerArgs) { this.callbackArgs.CompletedSynchronously = innerArgs.CompletedSynchronously; if (innerArgs.Exception != null) { this.callbackArgs.Exception = innerArgs.Exception; this.Complete(); } else { Fx.Assert(innerArgs.Transport != null, "must have a valid inner transport"); // upgrade transport this.callbackArgs.Transport = new TlsTransport(innerArgs.Transport, this.transportSettings); try { IAsyncResult result = this.callbackArgs.Transport.BeginOpen(this.timeoutHelper.RemainingTime(), onTransportOpened, this); if (result.CompletedSynchronously) { this.HandleTransportOpened(result); this.Complete(); } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } this.callbackArgs.Exception = exception; this.Complete(); } } }
public void ClientWebSocketTransportWriteWithoutConnectTest() { var websocket = new ClientWebSocket(); var clientWebSocketTransport = new ClientWebSocketTransport(websocket, null, null); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(byteArray, 0, byteArray.Length); clientWebSocketTransport.WriteAsync(args); }
public void ClientWebSocketTransportReadTest() { var websocket = new ClientWebSocket(); var clientWebSocketTransport = new ClientWebSocketTransport(websocket, IotHubName, null, null); TransportAsyncCallbackArgs args = new TransportAsyncCallbackArgs(); byte[] byteArray = new byte[10]; args.SetBuffer(byteArray, 0, 10); clientWebSocketTransport.ReadAsync(args); }
protected void OnTransportAccepted(TransportAsyncCallbackArgs args) { if (args.CompletedSynchronously) { ActionItem.Schedule(this.notifyAccept, args); } else { this.NotifyAccept(args); } }
public async Task ClientWebSocketTransportReadWithoutConnectTest() { var websocket = new ClientWebSocket(); var clientWebSocketTransport = new ClientWebSocketTransport(websocket, null, null); var args = new TransportAsyncCallbackArgs(); var byteArray = new byte[10]; args.SetBuffer(byteArray, 0, 10); if (clientWebSocketTransport.ReadAsync(args)) { while (!readComplete) { Thread.Sleep(TimeSpan.FromSeconds(1)); } } await websocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); }
public override bool WriteAsync(TransportAsyncCallbackArgs args) { this.ThrowIfNotOpen(); Fx.AssertAndThrow(args.Buffer != null || args.ByteBufferList != null, "must have a buffer to write"); Fx.AssertAndThrow(args.CompletedCallback != null, "must have a valid callback"); args.Exception = null; // null out any exceptions Task taskResult = this.WriteAsyncCore(args); if (WriteTaskDone(taskResult, args)) { return false; } taskResult.ToAsyncResult(onWriteComplete, args); return true; }
public override bool WriteAsync(TransportAsyncCallbackArgs args) { Fx.Assert(this.writeState.Args == null, "Cannot write when a write is still in progress"); ArraySegment<byte> buffer; if (args.Buffer != null) { buffer = new ArraySegment<byte>(args.Buffer, args.Offset, args.Count); this.writeState.Args = args; } else { Fx.Assert(args.ByteBufferList != null, "Buffer list should not be null when buffer is null"); if (args.ByteBufferList.Count == 1) { ByteBuffer byteBuffer = args.ByteBufferList[0]; buffer = new ArraySegment<byte>(byteBuffer.Buffer, byteBuffer.Offset, byteBuffer.Length); this.writeState.Args = args; } else { // Copy all buffers into one big buffer to avoid SSL overhead Fx.Assert(args.Count > 0, "args.Count should be set"); ByteBuffer temp = new ByteBuffer(args.Count, false, false); for (int i = 0; i < args.ByteBufferList.Count; ++i) { ByteBuffer byteBuffer = args.ByteBufferList[i]; Buffer.BlockCopy(byteBuffer.Buffer, byteBuffer.Offset, temp.Buffer, temp.Length, byteBuffer.Length); temp.Append(byteBuffer.Length); } buffer = new ArraySegment<byte>(temp.Buffer, 0, temp.Length); this.writeState.Args = args; this.writeState.Buffer = temp; } } IAsyncResult result = this.sslStream.BeginWrite(buffer.Array, buffer.Offset, buffer.Count, onWriteComplete, this); bool completedSynchronously = result.CompletedSynchronously; if (completedSynchronously) { this.HandleOperationComplete(result, true, true); } return !completedSynchronously; }
public override bool ConnectAsync(TimeSpan timeout, TransportAsyncCallbackArgs callbackArgs) { var streamSocket = new Windows.Networking.Sockets.StreamSocket(); var addr = this.transportSettings.Host; this.callbackArgs = callbackArgs; var connectTask = streamSocket.ConnectAsync(new Windows.Networking.HostName(addr), this.transportSettings.Port.ToString(), Windows.Networking.Sockets.SocketProtectionLevel.PlainSocket).AsTask(); connectTask.ContinueWith(_ => { TransportBase transport = null; Exception exception = null; try { transport = new TcpTransport(streamSocket, this.transportSettings); transport.Open(); } catch (Exception exp) { if (Fx.IsFatal(exp)) { throw; } exception = exp; if (transport != null) { transport.SafeClose(); } transport = null; } var completeSynchronously = false; this.callbackArgs.CompletedSynchronously = completeSynchronously; this.callbackArgs.Exception = exception; this.callbackArgs.Transport = transport; if (!completeSynchronously) { this.callbackArgs.CompletedCallback(this.callbackArgs); } }); return true; }
public void ReadWriteTest() { var websocket = new ClientWebSocket(); // Set SubProtocol to AMQPWSB10 websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Amqpwsb10); Uri uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix); websocket.ConnectAsync(uri, CancellationToken.None).Wait(CancellationToken.None); clientWebSocketTransport = new ClientWebSocketTransport(websocket, IotHubName, null, null); // Test Write API TransportAsyncCallbackArgs args = new TransportAsyncCallbackArgs(); args.CompletedCallback = onWriteOperationComplete; args.SetBuffer(byteArray, 0, byteArray.Length); clientWebSocketTransport.WriteAsync(args); // Test Read API args.CompletedCallback = onReadOperationComplete; clientWebSocketTransport.ReadAsync(args); }
public override bool ConnectAsync(TimeSpan timeout, TransportAsyncCallbackArgs callbackArgs) { AmqpTrace.Provider.AmqpLogOperationInformational(this, TraceOperation.Connect, this.transportSettings); TransportInitiator innerInitiator = this.transportSettings.CreateInitiator(); TransportAsyncCallbackArgs args = new TransportAsyncCallbackArgs(); args.CompletedCallback = this.OnConnectComplete; args.UserToken = callbackArgs; callbackArgs.CompletedSynchronously = false; this.timeoutHelper = new TimeoutHelper(timeout); if (innerInitiator.ConnectAsync(timeout, args)) { return true; } int currentThread = CurrentThreadId; Interlocked.Exchange(ref this.completingThread, currentThread); this.OnConnectComplete(args); return Interlocked.Exchange(ref this.completingThread, -1) != 0; }
public override bool ConnectAsync(TimeSpan timeout, TransportAsyncCallbackArgs callbackArgs) { this.callbackArgs = callbackArgs; this.timeoutHelper = new TimeoutHelper(timeout); TransportInitiator innerInitiator = this.transportSettings.InnerTransportSettings.CreateInitiator(); TransportAsyncCallbackArgs innerArgs = new TransportAsyncCallbackArgs(); innerArgs.CompletedCallback = OnInnerTransportConnected; innerArgs.UserToken = this; if (innerInitiator.ConnectAsync(timeout, innerArgs)) { // pending return true; } else { this.HandleInnerTransportConnected(innerArgs); return !this.callbackArgs.CompletedSynchronously; } }
async Task WriteAsyncCore(TransportAsyncCallbackArgs args) { bool succeeded = false; try { if (args.Buffer != null) { var arraySegment = new ArraySegment<byte>(args.Buffer, args.Offset, args.Count); await this.webSocket.SendAsync(arraySegment, WebSocketMessageType.Binary, true, this.writeCancellationTokenSource.Token); } else { foreach (ByteBuffer byteBuffer in args.ByteBufferList) { await this.webSocket.SendAsync(new ArraySegment<byte>(byteBuffer.Buffer, byteBuffer.Offset, byteBuffer.Length), WebSocketMessageType.Binary, true, this.writeCancellationTokenSource.Token); } } succeeded = true; } catch (WebSocketException webSocketException) { throw new IOException(webSocketException.Message, webSocketException); } catch (HttpListenerException httpListenerException) { throw new IOException(httpListenerException.Message, httpListenerException); } catch (TaskCanceledException taskCanceledException) { throw new TimeoutException(taskCanceledException.Message, taskCanceledException); } finally { if (!succeeded) { this.Abort(); } } }
async Task WriteAsyncCore(TransportAsyncCallbackArgs args) { bool succeeded = false; try { if (args.Buffer != null) { await this.webSocket.SendAsync(args.Buffer, args.Offset, args.Count, IotHubClientWebSocket.WebSocketMessageType.Binary, this.operationTimeout); } else { foreach (ByteBuffer byteBuffer in args.ByteBufferList) { await this.webSocket.SendAsync(byteBuffer.Buffer, byteBuffer.Offset, byteBuffer.Length, IotHubClientWebSocket.WebSocketMessageType.Binary, this.operationTimeout); } } succeeded = true; } catch (WebSocketException webSocketException) { throw new IOException(webSocketException.Message, webSocketException); } catch (HttpListenerException httpListenerException) { throw new IOException(httpListenerException.Message, httpListenerException); } catch (TaskCanceledException taskCanceledException) { throw new TimeoutException(taskCanceledException.Message, taskCanceledException); } finally { if (!succeeded) { this.Abort(); } } }
public async Task ReadWriteTest() { var websocket = new ClientWebSocket(); // Set SubProtocol to AMQPWSB10 websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Amqpwsb10); Uri uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix); await websocket.ConnectAsync(uri, CancellationToken.None); clientWebSocketTransport = new ClientWebSocketTransport(websocket, null, null); // Test Write API var args = new TransportAsyncCallbackArgs(); args.CompletedCallback = onWriteOperationComplete; args.SetBuffer(byteArray, 0, byteArray.Length); clientWebSocketTransport.WriteAsync(args); // Test Read API args.CompletedCallback = onReadOperationComplete; if (clientWebSocketTransport.ReadAsync(args)) { while (!readComplete) { Thread.Sleep(TimeSpan.FromSeconds(1)); } } // Once Read operation is complete, close websocket transport // Test Close API await clientWebSocketTransport.CloseAsync(TimeSpan.FromSeconds(30)); }
public void Reset() { this.Args = null; this.Buffer = null; }
static void OnReadOperationComplete(TransportAsyncCallbackArgs args) { if (args.Exception != null) { throw args.Exception; } // Verify that data matches what was sent if (byteArray.Length != args.Count) { throw new InvalidOperationException("Expected " + byteArray.Length + " bytes in response"); } for (int i = 0; i < args.Count; i++) { if (byteArray[i] != args.Buffer[i]) { throw new InvalidOperationException("Response contents do not match what was sent"); } } readComplete = true; }
async Task<int> ReadAsyncCore(TransportAsyncCallbackArgs args) { bool succeeded = false; try { WebSocketReceiveResult receiveResult = await this.webSocket.ReceiveAsync( new ArraySegment<byte>(args.Buffer, args.Offset, args.Count), CancellationToken.None); succeeded = true; return receiveResult.Count; } catch (WebSocketException webSocketException) { throw new IOException(webSocketException.Message, webSocketException); } catch (HttpListenerException httpListenerException) { throw new IOException(httpListenerException.Message, httpListenerException); } catch (TaskCanceledException taskCanceledException) { throw new TimeoutException(taskCanceledException.Message, taskCanceledException); } finally { if (!succeeded) { this.Abort(); } } }
static void OnWriteOperationComplete(TransportAsyncCallbackArgs args) { if (args.BytesTransfered != byteArray.Length) { throw new InvalidOperationException("All the bytes sent were not transferred"); } if (args.Exception != null) { throw args.Exception; } }
public async Task LegacyWebSocketReadWriteTest() { var websocket = new IotHubClientWebSocket(WebSocketConstants.SubProtocols.Amqpwsb10); await websocket.ConnectAsync(IotHubName, Port, "ws://", TimeSpan.FromMinutes(1)); legacyClientWebSocketTransport = new LegacyClientWebSocketTransport(websocket, TimeSpan.FromSeconds(60), null, null); // Test Write API TransportAsyncCallbackArgs args = new TransportAsyncCallbackArgs(); args.CompletedCallback = onWriteOperationComplete; args.SetBuffer(byteArray, 0, byteArray.Length); legacyClientWebSocketTransport.WriteAsync(args); // Test Read API args.CompletedCallback = onReadOperationComplete; if (legacyClientWebSocketTransport.ReadAsync(args)) { while (!readComplete) { Thread.Sleep(TimeSpan.FromSeconds(1)); } } // Once Read operation is complete, close websocket transport legacyClientWebSocketTransport.CloseAsync(TimeSpan.FromSeconds(30)).Wait(CancellationToken.None); }
static void OnInnerTransportConnected(TransportAsyncCallbackArgs innerArgs) { TlsTransportInitiator thisPtr = (TlsTransportInitiator)innerArgs.UserToken; thisPtr.HandleInnerTransportConnected(innerArgs); }
public void LegacyClientWebSocketTransportWriteWithoutConnectTest() { var websocket = new IotHubClientWebSocket(WebSocketConstants.SubProtocols.Amqpwsb10); var clientWebSocketTransport = new LegacyClientWebSocketTransport(websocket, TimeSpan.FromSeconds(60), null, null); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(byteArray, 0, byteArray.Length); clientWebSocketTransport.WriteAsync(args); }
public async Task LegacyClientWebSocketTransportReadWithoutConnectTest() { var websocket = new IotHubClientWebSocket(WebSocketConstants.SubProtocols.Amqpwsb10); var clientWebSocketTransport = new LegacyClientWebSocketTransport(websocket, TimeSpan.FromSeconds(60), null, null); var args = new TransportAsyncCallbackArgs(); var byteArray = new byte[10]; args.SetBuffer(byteArray, 0, 10); if (clientWebSocketTransport.ReadAsync(args)) { while (!readComplete) { Thread.Sleep(TimeSpan.FromSeconds(1)); } } await websocket.CloseAsync(); }
public async Task WriteAfterAbortTest() { var websocket = new ClientWebSocket(); // Set SubProtocol to AMQPWSB10 websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Amqpwsb10); Uri uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix); await websocket.ConnectAsync(uri, CancellationToken.None); clientWebSocketTransport = new ClientWebSocketTransport(websocket, null, null); clientWebSocketTransport.Abort(); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(byteArray, 0, byteArray.Length); clientWebSocketTransport.WriteAsync(args); }
public async Task ReadAfterCloseTest() { var websocket = new ClientWebSocket(); // Set SubProtocol to AMQPWSB10 websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Amqpwsb10); var uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix); await websocket.ConnectAsync(uri, CancellationToken.None); clientWebSocketTransport = new ClientWebSocketTransport(websocket, null, null); await clientWebSocketTransport.CloseAsync(TimeSpan.FromSeconds(30)); var args = new TransportAsyncCallbackArgs(); var byteArray = new byte[10]; args.SetBuffer(byteArray, 0, 10); args.CompletedCallback = onReadOperationComplete; clientWebSocketTransport.ReadAsync(args); }
void OnAcceptTransport(TransportListener innerListener, TransportAsyncCallbackArgs args) { AmqpTrace.Provider.AmqpLogOperationVerbose(this, TraceOperation.Execute, "OnAcceptTransport"); TransportHandler.SpawnHandler(this, args); }
public sealed override bool ReadAsync(TransportAsyncCallbackArgs args) { throw new NotImplementedException("Not supported in UWP"); }
public async Task LegacyWebSocketWriteAfterCloseTest() { var websocket = new IotHubClientWebSocket(WebSocketConstants.SubProtocols.Amqpwsb10); await websocket.ConnectAsync(IotHubName, Port, "ws://", TimeSpan.FromMinutes(1)); legacyClientWebSocketTransport = new LegacyClientWebSocketTransport(websocket, TimeSpan.FromMinutes(1), null, null); await legacyClientWebSocketTransport.CloseAsync(TimeSpan.FromSeconds(30)); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(byteArray, 0, byteArray.Length); legacyClientWebSocketTransport.WriteAsync(args); }
public override bool WriteAsync(TransportAsyncCallbackArgs args) { Fx.Assert(this.writeState.Args == null, "Cannot write when a write is still in progress"); Windows.Storage.Streams.IBuffer ibuffer; if (args.Buffer != null) { this.writeState.Args = args; ibuffer = args.Buffer.AsBuffer(args.Offset, args.Count); } else { Fx.Assert(args.ByteBufferList != null, "Buffer list should not be null when buffer is null"); ArraySegment <byte> buffer; if (args.ByteBufferList.Count == 1) { ByteBuffer byteBuffer = args.ByteBufferList[0]; buffer = new ArraySegment <byte>(byteBuffer.Buffer, byteBuffer.Offset, byteBuffer.Length); this.writeState.Args = args; } else { // Copy all buffers into one big buffer to avoid SSL overhead Fx.Assert(args.Count > 0, "args.Count should be set"); ByteBuffer temp = new ByteBuffer(args.Count, false, false); for (int i = 0; i < args.ByteBufferList.Count; ++i) { ByteBuffer byteBuffer = args.ByteBufferList[i]; Buffer.BlockCopy(byteBuffer.Buffer, byteBuffer.Offset, temp.Buffer, temp.Length, byteBuffer.Length); temp.Append(byteBuffer.Length); } buffer = new ArraySegment <byte>(temp.Buffer, 0, temp.Length); this.writeState.Args = args; this.writeState.Buffer = temp; } ibuffer = buffer.Array.AsBuffer(0, buffer.Count); } var t = this.socket.OutputStream.WriteAsync(ibuffer).AsTask(); t.ContinueWith(completion => { var args2 = this.readState.Args; if (completion.IsFaulted) { if (Fx.IsFatal(completion.Exception)) { throw completion.Exception; } args2.Exception = completion.Exception; } else { args2 = this.writeState.Args; ByteBuffer buffer = this.writeState.Buffer; this.writeState.Reset(); if (buffer != null) { buffer.Dispose(); } Fx.Assert(args2.Count == completion.Result, "completion must have the same write count"); args2.BytesTransfered = args2.Count; } args2.CompletedSynchronously = false; Action <TransportAsyncCallbackArgs> callback = args2.CompletedCallback; if (callback != null) { args2.CompletedCallback(args2); } }); return(true); }
public async Task LegacyWebSocketWriteAfterAbortTest() { var websocket = new IotHubClientWebSocket(WebSocketConstants.SubProtocols.Amqpwsb10); await websocket.ConnectAsync(IotHubName, Port, "ws://", TimeSpan.FromMinutes(1)); legacyClientWebSocketTransport = new LegacyClientWebSocketTransport(websocket, TimeSpan.FromMinutes(1), null, null); legacyClientWebSocketTransport.Abort(); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(byteArray, 0, byteArray.Length); legacyClientWebSocketTransport.WriteAsync(args); Assert.Fail("Did not throw object disposed exception"); }
public static void SpawnHandler(AmqpTransportListener parent, TransportAsyncCallbackArgs args) { TransportHandler handler = new TransportHandler(parent, args); ActionItem.Schedule(s => Start(s), handler); }
static bool WriteTaskDone(Task taskResult, TransportAsyncCallbackArgs args) { IAsyncResult result = taskResult; args.BytesTransfered = 0; // reset bytes transferred if (taskResult.IsFaulted) { args.Exception = taskResult.Exception; return true; } else if (taskResult.IsCompleted) { args.BytesTransfered = args.Count; args.CompletedSynchronously = result.CompletedSynchronously; return true; } else if (taskResult.IsCanceled) // This should not happen since TaskCanceledException is handled in WriteAsyncCore. { return true; } return false; }