/// <summary> /// <para>Events:</para> /// <para>@emits transportclose</para> /// <para>@emits dataproducerclose</para> /// <para>@emits message - (message: Buffer, ppid: number)</para> /// <para>@emits sctpsendbufferfull</para> /// <para>@emits bufferedamountlow - (bufferedAmount: number)</para> /// <para>@emits @close</para> /// <para>@emits @dataproducerclose</para> /// <para>Observer events:</para> /// <para>@emits close</para> /// </summary> /// <param name="loggerFactory"></param> /// <param name="dataConsumerInternalData"></param> /// <param name="sctpStreamParameters"></param> /// <param name="label"></param> /// <param name="protocol"></param> /// <param name="channel"></param> /// <param name="payloadChannel"></param> /// <param name="appData"></param> public DataConsumer(ILoggerFactory loggerFactory, DataConsumerInternalData dataConsumerInternalData, SctpStreamParameters sctpStreamParameters, string label, string protocol, Channel channel, PayloadChannel payloadChannel, Dictionary <string, object>?appData ) { _logger = loggerFactory.CreateLogger <DataConsumer>(); // Internal _internal = dataConsumerInternalData; // Data SctpStreamParameters = sctpStreamParameters; Label = label; Protocol = protocol; _channel = channel; _payloadChannel = payloadChannel; AppData = appData; HandleWorkerNotifications(); }
/// <summary> /// Create a DataConsumer. /// </summary> /// <param name="dataConsumerOptions"></param> /// <returns></returns> public async Task <DataConsumer> ConsumeDataAsync(DataConsumerOptions dataConsumerOptions) { _logger.LogDebug("ConsumeDataAsync()"); if (dataConsumerOptions.DataProducerId.IsNullOrWhiteSpace()) { throw new Exception("missing dataProducerId"); } var dataProducer = GetDataProducerById(dataConsumerOptions.DataProducerId); if (dataProducer == null) { throw new Exception($"DataProducer with id {dataConsumerOptions.DataProducerId} not found"); } var sctpStreamParameters = dataProducer.SctpStreamParameters.DeepClone <SctpStreamParameters>(); // This may throw. var sctpStreamId = GetNextSctpStreamId(); if (_sctpStreamIds == null || sctpStreamId > _sctpStreamIds.Length - 1) { throw new IndexOutOfRangeException(nameof(_sctpStreamIds)); } _sctpStreamIds[sctpStreamId] = 1; sctpStreamParameters.StreamId = sctpStreamId; var @internal = new DataConsumerInternalData ( Internal.RouterId, Internal.TransportId, dataConsumerOptions.DataProducerId, Guid.NewGuid().ToString() ); var reqData = new { SctpStreamParameters = sctpStreamParameters, dataProducer.Label, dataProducer.Protocol }; var status = await Channel.RequestAsync(MethodId.TRANSPORT_CONSUME_DATA, @internal, reqData); var responseData = JsonConvert.DeserializeObject <TransportDataConsumeResponseData>(status); var dataConsumer = new DataConsumer(_loggerFactory, @internal, responseData.SctpStreamParameters, responseData.Label, responseData.Protocol, Channel, AppData); DataConsumers[dataConsumer.Internal.DataConsumerId] = dataConsumer; dataConsumer.On("@close", _ => { DataConsumers.Remove(dataConsumer.Internal.DataConsumerId); _sctpStreamIds[sctpStreamId] = 0; }); dataConsumer.On("@dataproducerclose", _ => { DataConsumers.Remove(dataConsumer.Internal.DataConsumerId); _sctpStreamIds[sctpStreamId] = 0; }); // Emit observer event. Observer.Emit("newdataconsumer", dataConsumer); return(dataConsumer); }
/// <summary> /// Create a DataConsumer. /// </summary> /// <param name="dataConsumerOptions"></param> /// <returns></returns> public async Task <DataConsumer> ConsumeDataAsync(DataConsumerOptions dataConsumerOptions) { _logger.LogDebug("ConsumeDataAsync()"); if (dataConsumerOptions.DataProducerId.IsNullOrWhiteSpace()) { throw new Exception("missing dataProducerId"); } var dataProducer = GetDataProducerById(dataConsumerOptions.DataProducerId); if (dataProducer == null) { throw new Exception($"DataProducer with id {dataConsumerOptions.DataProducerId} not found"); } DataProducerType type; SctpStreamParameters?sctpStreamParameters = null; int sctpStreamId = -1; // If this is not a DirectTransport, use sctpStreamParameters from the // DataProducer (if type 'sctp') unless they are given in method parameters. if (GetType() != typeof(DirectTransport)) { type = DataProducerType.Sctp; sctpStreamParameters = dataProducer.SctpStreamParameters.DeepClone <SctpStreamParameters>(); // This may throw. sctpStreamId = GetNextSctpStreamId(); if (_sctpStreamIds == null || sctpStreamId > _sctpStreamIds.Length - 1) { throw new IndexOutOfRangeException(nameof(_sctpStreamIds)); } _sctpStreamIds[sctpStreamId] = 1; sctpStreamParameters.StreamId = sctpStreamId; } // If this is a DirectTransport, sctpStreamParameters must not be used. else { type = DataProducerType.Direct; if (dataConsumerOptions.Ordered.HasValue || dataConsumerOptions.MaxPacketLifeTime.HasValue || dataConsumerOptions.MaxRetransmits.HasValue ) { _logger.LogWarning("ConsumeDataAsync() | ordered, maxPacketLifeTime and maxRetransmits are ignored when consuming data on a DirectTransport"); } } var @internal = new DataConsumerInternalData ( Internal.RouterId, Internal.TransportId, dataConsumerOptions.DataProducerId, Guid.NewGuid().ToString() ); var reqData = new { Type = type.GetEnumStringValue(), SctpStreamParameters = sctpStreamParameters, dataProducer.Label, dataProducer.Protocol }; var status = await Channel.RequestAsync(MethodId.TRANSPORT_CONSUME_DATA, @internal, reqData); var responseData = JsonConvert.DeserializeObject <TransportDataConsumeResponseData>(status !); var dataConsumer = new DataConsumer(_loggerFactory, @internal, responseData.SctpStreamParameters, responseData.Label, responseData.Protocol, Channel, PayloadChannel, AppData); DataConsumers[dataConsumer.DataConsumerId] = dataConsumer; dataConsumer.On("@close", _ => { DataConsumers.Remove(dataConsumer.DataConsumerId); if (_sctpStreamIds != null && sctpStreamId >= 0) { _sctpStreamIds[sctpStreamId] = 0; } }); dataConsumer.On("@dataproducerclose", _ => { DataConsumers.Remove(dataConsumer.DataConsumerId); if (_sctpStreamIds != null && sctpStreamId >= 0) { _sctpStreamIds[sctpStreamId] = 0; } }); // Emit observer event. Observer.Emit("newdataconsumer", dataConsumer); return(dataConsumer); }