/// <summary> /// Read responses from socket /// </summary> /// <param name="ct"></param> /// <returns></returns> public async Task <BrowseResponse> BrowseNextAsync(CancellationToken ct) { if (!_connected) { throw new SocketException(SocketError.Closed); } Message message; while (!ReceiveQueue.TryDequeue(out message)) { await ReceiveAsync(ct).ConfigureAwait(false); } ProxySocket.ThrowIfFailed(message); if (message.Error != (int)SocketError.Success) { throw new SocketException((SocketError)message.Error); } if (message.TypeId != MessageContent.Data) { throw new SocketException("No data message"); } var data = message.Content as DataMessage; if (data == null) { throw new SocketException("Bad data"); } var stream = new MemoryStream(data.Payload); var response = await BrowseResponse.DecodeAsync(stream, _codec, ct); response.Interface = message.Proxy.ToSocketAddress(); return(response); }
/// <summary> /// Create receive block /// </summary> protected virtual void CreateReceiveBlock() { _receive = new TransformManyBlock <Message, Message>((message) => { if (message.Error == (int)SocketError.Closed || message.TypeId == MessageContent.Close) { // Remote side closed throw new SocketException("Remote side closed", null, SocketError.Closed); } if (message.Error == (int)SocketError.Duplicate) { return(Enumerable.Empty <Message>()); } if (message.Error != (int)SocketError.Success) { ProxySocket.ThrowIfFailed(message); } else if (message.TypeId == MessageContent.Data) { return(message.AsEnumerable()); } // Todo: log error? return(Enumerable.Empty <Message>()); }, new ExecutionDataflowBlockOptions { NameFormat = "Receive (in Link) Id={1}", EnsureOrdered = true, MaxMessagesPerTask = DataflowBlockOptions.Unbounded, SingleProducerConstrained = true, BoundedCapacity = 3 }); }
// // Create socket for address family // public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, uint keepAlive) { _internal = ProxySocket.Create(new SocketInfo { Family = addressFamily, Protocol = protocolType, Type = socketType, Timeout = keepAlive }, Provider); }
/// <summary> /// Send socket option message /// </summary> /// <param name="option"></param> /// <param name="value"></param> /// <param name="ct"></param> public async Task SetSocketOptionAsync( SocketOption option, ulong value, CancellationToken ct) { var response = await _socket.Provider.ControlChannel.CallAsync(Proxy, new Message(_socket.Id, RemoteId, new SetOptRequest( new Property <ulong>((uint)option, value))), ct).ConfigureAwait(false); ProxySocket.ThrowIfFailed(response); }
/// <summary> /// Constructor for proxy link object /// </summary> /// <param name="socket"></param> /// <param name="proxy"></param> /// <param name="remoteId"></param> /// <param name="localAddress"></param> /// <param name="peerAddress"></param> internal ProxyLink(ProxySocket socket, INameRecord proxy, Reference remoteId, SocketAddress localAddress, SocketAddress peerAddress) { _socket = socket ?? throw new ArgumentNullException(nameof(socket)); Proxy = proxy ?? throw new ArgumentNullException(nameof(proxy)); RemoteId = remoteId ?? throw new ArgumentNullException(nameof(remoteId)); LocalAddress = localAddress ?? throw new ArgumentNullException(nameof(localAddress)); PeerAddress = peerAddress ?? throw new ArgumentNullException(nameof(peerAddress)); }
/// <summary> /// Constructor for proxy link object /// </summary> /// <param name="socket"></param> /// <param name="proxy"></param> /// <param name="remoteId"></param> /// <param name="localAddress"></param> /// <param name="peerAddress"></param> internal ProxyLink(ProxySocket socket, INameRecord proxy, Reference remoteId, SocketAddress localAddress, SocketAddress peerAddress) { _streamId = new Reference(); _socket = socket; Proxy = proxy; RemoteId = remoteId; LocalAddress = localAddress; PeerAddress = peerAddress; }
/// <summary> /// Send socket option message /// </summary> /// <param name="option"></param> /// <param name="value"></param> /// <param name="ct"></param> public async Task SetSocketOptionAsync( SocketOption option, ulong value, CancellationToken ct) { using (var request = Message.Create(_socket.Id, RemoteId, SetOptRequest.Create( Property <ulong> .Create((uint)option, value)))) { var response = await _socket.Provider.ControlChannel.CallAsync( Proxy, request, TimeSpan.MaxValue, ct).ConfigureAwait(false); ProxySocket.ThrowIfFailed(response); } }
/// <summary> /// Get socket option /// </summary> /// <param name="option"></param> /// <param name="ct"></param> /// <returns></returns> public async Task <ulong> GetSocketOptionAsync( SocketOption option, CancellationToken ct) { var response = await _socket.Provider.ControlChannel.CallAsync(Proxy, new Message(_socket.Id, RemoteId, new GetOptRequest( option)), ct).ConfigureAwait(false); ProxySocket.ThrowIfFailed(response); var optionValue = ((GetOptResponse)response.Content).OptionValue as Property <ulong>; if (optionValue == null) { throw new ProxyException("Bad option value returned"); } return(optionValue.Value); }
/// <summary> /// Receive a message /// </summary> /// <param name="buffer"></param> /// <param name="ct"></param> /// <returns></returns> protected async Task <DataMessage> ReceiveAsync( CancellationToken ct) { Message message; while (!Socket.ReceiveQueue.TryDequeue(out message)) { await Socket.ReceiveAsync(ct).ConfigureAwait(false); } ProxySocket.ThrowIfFailed(message); if (message.Error != (int)SocketError.Success) { throw new SocketException((SocketError)message.Error); } if (message.TypeId != MessageContent.Data) { throw new SocketException("No data message"); } return(message.Content as DataMessage); }
internal ProxyStream(ProxySocket socket) { Socket = socket; }
/// <summary> /// Constructor /// </summary> /// <param name="socket"></param> internal ListenStream(ProxySocket socket) : base(socket) { }
/// <summary> /// Constructor /// </summary> /// <param name="socket"></param> internal PacketStream(ProxySocket socket) : base(socket) { }
/// <summary> /// Constructor /// </summary> /// <param name="socket"></param> internal SequentialStream(ProxySocket socket) : base(socket) { }