Exemple #1
0
        /// <summary>
        /// Perform event to message Json encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeAsJson(
            IEnumerable <DataSetMessageModel> messages)
        {
            var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Json);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            var encodingContext = messages.First().ServiceMessageContext;

            foreach (var networkMessage in notifications)
            {
                var writer  = new StringWriter();
                var encoder = new JsonEncoderEx(writer, encodingContext)
                {
                    UseAdvancedEncoding   = true,
                    UseUriEncoding        = true,
                    UseReversibleEncoding = false
                };
                networkMessage.Encode(encoder);
                encoder.Close();
                var encoded = new NetworkMessageModel {
                    Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                    ContentEncoding = "utf-8",
                    Timestamp       = DateTime.UtcNow,
                    ContentType     = ContentMimeType.UaLegacyPublisher,
                    MessageSchema   = MessageSchemaTypes.MonitoredItemMessageJson
                };
                yield return(encoded);
            }
        }
 /// <summary>
 /// Perform json encoding
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public IEnumerable <NetworkMessageModel> EncodeAsJson(DataSetMessageModel message)
 {
     foreach (var networkMessage in GetNetworkMessages(message.YieldReturn()))
     {
         using (var writer = new StringWriter()) {
             using (var encoder = new JsonEncoderEx(writer, message.ServiceMessageContext)
             {
                 UseAdvancedEncoding = true,
                 UseUriEncoding = true,
                 UseReversibleEncoding = false
             }) {
                 networkMessage.Encode(encoder);
             }
             var json    = writer.ToString();
             var encoded = new NetworkMessageModel {
                 Body            = Encoding.UTF8.GetBytes(json),
                 ContentEncoding = "utf-8",
                 Timestamp       = DateTime.UtcNow,
                 ContentType     = ContentMimeType.Json,
                 MessageId       = message.SequenceNumber.ToString(),
                 MessageSchema   = MessageSchemaTypes.NetworkMessageJson
             };
             yield return(encoded);
         }
     }
 }
 /// <summary>
 /// Perform event to message encoding
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public IEnumerable <NetworkMessageModel> Encode(DataSetMessageModel message)
 {
     foreach (var notification in message.Notifications)
     {
         var value = new MonitoredItemMessage {
             MessageContentMask = (message.Writer?.MessageSettings?
                                   .DataSetMessageContentMask).ToMonitoredItemMessageMask(
                 message.Writer?.DataSetFieldContentMask),
             ApplicationUri  = message.ApplicationUri,
             EndpointUrl     = message.EndpointUrl,
             ExtensionFields = message.Writer?.DataSet?.ExtensionFields,
             NodeId          = notification.NodeId,
             Value           = notification.Value,
             DisplayName     = notification.DisplayName
         };
         using (var writer = new StringWriter()) {
             using (var encoder = new JsonEncoderEx(writer, message.ServiceMessageContext)
             {
                 // TODO: Configure encoding further
                 UseUriEncoding = true
             }) {
                 value.Encode(encoder);
             }
             var encoded = new NetworkMessageModel {
                 Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                 ContentEncoding = "utf-8",
                 Timestamp       = DateTime.UtcNow,
                 ContentType     = ContentMimeType.Json,
                 MessageId       = message.SequenceNumber.ToString(),
                 MessageSchema   = MessageSchemaTypes.MonitoredItemMessageJson
             };
             yield return(encoded);
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Perform event to message binary encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeAsUadp(
            IEnumerable <DataSetMessageModel> messages)
        {
            var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Uadp);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            var encodingContext = messages.First().ServiceMessageContext;

            foreach (var networkMessage in notifications)
            {
                var encoder = new BinaryEncoder(encodingContext);
                encoder.WriteBoolean(null, false); // is not Batch
                encoder.WriteEncodeable(null, networkMessage);
                var encoded = new NetworkMessageModel {
                    Body          = encoder.CloseAndReturnBuffer(),
                    Timestamp     = DateTime.UtcNow,
                    ContentType   = ContentMimeType.UaBinary,
                    MessageSchema = MessageSchemaTypes.MonitoredItemMessageBinary
                };
                yield return(encoded);
            }
        }
Exemple #5
0
 /// <summary>
 /// Perform event to message encoding
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public IEnumerable <NetworkMessageModel> EncodeAsUadp(DataSetMessageModel message)
 {
     foreach (var notification in message.Notifications)
     {
         using (var encoder = new BinaryEncoder(message.ServiceMessageContext)) {
             var value = new MonitoredItemMessage {
                 MessageContentMask = (message.Writer?.MessageSettings?
                                       .DataSetMessageContentMask).ToMonitoredItemMessageMask(
                     message.Writer?.DataSetFieldContentMask),
                 ApplicationUri  = message.ApplicationUri,
                 SubscriptionId  = message.SubscriptionId,
                 EndpointUrl     = message.EndpointUrl,
                 ExtensionFields = message.Writer?.DataSet?.ExtensionFields,
                 NodeId          = notification.NodeId.ToExpandedNodeId(message.ServiceMessageContext.NamespaceUris),
                 Timestamp       = message.TimeStamp ?? DateTime.UtcNow,
                 Value           = notification.Value,
                 DisplayName     = notification.DisplayName
             };
             value.Encode(encoder);
             var encoded = new NetworkMessageModel {
                 Body            = encoder.CloseAndReturnBuffer(),
                 ContentEncoding = "utf-8",
                 Timestamp       = DateTime.UtcNow,
                 ContentType     = ContentMimeType.UaBinary,
                 MessageId       = message.SequenceNumber.ToString(),
                 MessageSchema   = MessageSchemaTypes.MonitoredItemMessageBinary
             };
             yield return(encoded);
         }
     }
 }
        public PCNetworkManager(NetworkMessagesEventArgs incomingMsg)
        {
            SQLiteCRUD          sql    = new SQLiteCRUD(ConnectionStringManager.GetConnectionString(ConnectionStringManager.DataBases.PCControllerDB));
            NetworkMessageModel netMsg = new NetworkMessageModel();

            if (incomingMsg.IncomingMessage is null)
            {
                netMsg.IncomingMessage = string.Empty;
            }
            else
            {
                netMsg.IncomingMessage = incomingMsg.IncomingMessage;
            }

            if (incomingMsg.OutgoingMessage is null)
            {
                netMsg.IncomingMessage = string.Empty;
            }
            else
            {
                netMsg.OutgoingMessage = incomingMsg.OutgoingMessage;
            }

            if (incomingMsg.RemoteIP is null)
            {
                incomingMsg.RemoteIP = string.Empty;
            }
            else
            {
                netMsg.RemoteIP = incomingMsg.RemoteIP;
            }

            if (incomingMsg.IncomingMessage is null)
            {
                incomingMsg.Timestamp = string.Empty;
            }
            else
            {
                netMsg.Timestamp = incomingMsg.Timestamp;
            }

            if (incomingMsg.RemotePort is null)
            {
                incomingMsg.RemotePort = string.Empty;
            }
            else
            {
                netMsg.RemotePort = incomingMsg.RemotePort;
            }

            netMsg.UDPPort = incomingMsg.UDPPort;

            this.UDPPortSet?.Invoke(this, incomingMsg.UDPPort);

            sql.InsertNetMessage(netMsg);
        }
Exemple #7
0
        /// <summary>
        /// Perform DataSetMessageModel to batch NetworkMessageModel using binary encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxEncodedSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp(
            IEnumerable <DataSetMessageModel> messages, int maxEncodedSize)
        {
            var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Uadp);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            // take the message context of the first element since is the same for all messages
            var encodingContext = messages.First().ServiceMessageContext;
            var current         = notifications.GetEnumerator();
            var processing      = current.MoveNext();
            var messageSize     = 4; // array length size

            maxEncodedSize -= 2048;  // reserve 2k for header
            var chunk = new Collection <MonitoredItemMessage>();

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperEncoder = new BinaryEncoder(encodingContext);
                    helperEncoder.WriteEncodeable(null, notification);
                    var notificationSize = helperEncoder.CloseAndReturnBuffer().Length;
                    messageCompleted = maxEncodedSize < (messageSize + notificationSize);
                    if (!messageCompleted)
                    {
                        chunk.Add(notification);
                        processing   = current.MoveNext();
                        messageSize += notificationSize;
                    }
                }
                if (!processing || messageCompleted)
                {
                    var encoder = new BinaryEncoder(encodingContext);
                    encoder.WriteBoolean(null, true); // is Batch
                    encoder.WriteEncodeableArray(null, chunk);
                    chunk.Clear();
                    messageSize = 4;
                    var encoded = new NetworkMessageModel {
                        Body          = encoder.CloseAndReturnBuffer(),
                        Timestamp     = DateTime.UtcNow,
                        ContentType   = ContentMimeType.UaBinary,
                        MessageSchema = MessageSchemaTypes.MonitoredItemMessageBinary
                    };
                    yield return(encoded);
                }
            }
        }
        /// <summary>
        /// Perform json encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeAsJson(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetNetworkMessages(messages, MessageEncoding.Json, encodingContext);

            if (!notifications.Any())
            {
                yield break;
            }
            var routingInfo = messages.FirstOrDefault(m => m?.WriterGroup != null)?.WriterGroup.WriterGroupId;

            foreach (var networkMessage in notifications)
            {
                int notificationsPerMessage = networkMessage.Messages.Sum(m => m.Payload.Count);
                var writer  = new StringWriter();
                var encoder = new JsonEncoderEx(writer, encodingContext)
                {
                    UseAdvancedEncoding   = true,
                    UseUriEncoding        = true,
                    UseReversibleEncoding = false
                };
                networkMessage.Encode(encoder);
                encoder.Close();
                var encoded = new NetworkMessageModel {
                    Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                    ContentEncoding = "utf-8",
                    Timestamp       = DateTime.UtcNow,
                    ContentType     = ContentMimeType.Json,
                    MessageSchema   = MessageSchemaTypes.NetworkMessageJson,
                    RoutingInfo     = _enableRoutingInfo ? routingInfo : null,
                };
                if (encoded.Body.Length > maxMessageSize)
                {
                    // Message too large, drop it.
                    NotificationsDroppedCount += (uint)notificationsPerMessage;
                    _logger.Warning("Message too large, dropped {notificationsPerMessage} values", notificationsPerMessage);
                    continue;
                }
                NotificationsProcessedCount += (uint)notificationsPerMessage;
                AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                 (MessagesProcessedCount + 1);
                AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) /
                                             (MessagesProcessedCount + 1);
                MessagesProcessedCount++;
                yield return(encoded);
            }
        }
        /// <summary>
        /// Perform json encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeAsJson(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetNetworkMessages(messages, MessageEncoding.Json, encodingContext);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            foreach (var networkMessage in notifications)
            {
                ulong notificationsPerMessage = (ulong)networkMessage.Messages.Sum(m => m.Payload.Count);
                var   writer  = new StringWriter();
                var   encoder = new JsonEncoderEx(writer, encodingContext)
                {
                    UseAdvancedEncoding   = true,
                    UseUriEncoding        = true,
                    UseReversibleEncoding = false
                };
                networkMessage.Encode(encoder);
                encoder.Close();
                var encoded = new NetworkMessageModel {
                    Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                    ContentEncoding = "utf-8",
                    Timestamp       = DateTime.UtcNow,
                    ContentType     = ContentMimeType.Json,
                    MessageSchema   = MessageSchemaTypes.NetworkMessageJson
                };
                if (encoded.Body.Length > maxMessageSize)
                {
                    // this message is too large to be processed. Drop it
                    // TODO Trace
                    NotificationsDroppedCount++;
                    yield break;
                }
                NotificationsProcessedCount++;
                AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                 (MessagesProcessedCount + 1);
                AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) /
                                             (MessagesProcessedCount + 1);
                MessagesProcessedCount++;
                yield return(encoded);
            }
        }
 /// <summary>
 /// Perform uadp encoding
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public IEnumerable <NetworkMessageModel> EncodeAsUadp(DataSetMessageModel message)
 {
     foreach (var networkMessage in GetNetworkMessages(message.YieldReturn()))
     {
         using (var encoder = new BinaryEncoder(message.ServiceMessageContext)) {
             networkMessage.Encode(encoder);
             var encoded = new NetworkMessageModel {
                 Body          = encoder.CloseAndReturnBuffer(),
                 Timestamp     = DateTime.UtcNow,
                 ContentType   = ContentMimeType.Uadp,
                 MessageId     = message.SequenceNumber.ToString(),
                 MessageSchema = MessageSchemaTypes.NetworkMessageUadp
             };
             yield return(encoded);
         }
     }
 }
        /// <summary>
        /// Perform uadp encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeAsUadp(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp, encodingContext);

            if (!notifications.Any())
            {
                yield break;
            }
            var routingInfo = messages.FirstOrDefault(m => m?.WriterGroup != null)?.WriterGroup.WriterGroupId;

            foreach (var networkMessage in notifications)
            {
                int notificationsPerMessage = networkMessage.Messages.Sum(m => m.Payload.Count);
                var encoder = new BinaryEncoder(encodingContext);
                encoder.WriteBoolean(null, false); // is not Batch
                encoder.WriteEncodeable(null, networkMessage);
                networkMessage.Encode(encoder);
                var encoded = new NetworkMessageModel {
                    Body          = encoder.CloseAndReturnBuffer(),
                    Timestamp     = DateTime.UtcNow,
                    ContentType   = ContentMimeType.Uadp,
                    MessageSchema = MessageSchemaTypes.NetworkMessageUadp,
                    RoutingInfo   = _enableRoutingInfo ? routingInfo : null,
                };
                if (encoded.Body.Length > maxMessageSize)
                {
                    // Message too large, drop it.
                    NotificationsDroppedCount += (uint)notificationsPerMessage;
                    _logger.Warning("Message too large, dropped {notificationsPerMessage} values", notificationsPerMessage);
                    continue;
                }
                NotificationsProcessedCount += (uint)notificationsPerMessage;
                AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                 (MessagesProcessedCount + 1);
                AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) /
                                             (MessagesProcessedCount + 1);
                MessagesProcessedCount++;
                yield return(encoded);
            }
        }
        /// <summary>
        /// Perform uadp encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeAsUadp(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp, encodingContext);

            if (notifications.Count() == 0)
            {
                yield break;
            }

            foreach (var networkMessage in notifications)
            {
                ulong notificationsPerMessage = (ulong)networkMessage.Messages.Sum(m => m.Payload.Count);
                var   encoder = new BinaryEncoder(encodingContext);
                encoder.WriteBoolean(null, false); // is not Batch
                encoder.WriteEncodeable(null, networkMessage);
                networkMessage.Encode(encoder);
                var encoded = new NetworkMessageModel {
                    Body          = encoder.CloseAndReturnBuffer(),
                    Timestamp     = DateTime.UtcNow,
                    ContentType   = ContentMimeType.Uadp,
                    MessageSchema = MessageSchemaTypes.NetworkMessageUadp
                };
                if (encoded.Body.Length > maxMessageSize)
                {
                    // this message is too large to be processed. Drop it
                    // TODO Trace
                    NotificationsDroppedCount++;
                    yield break;
                }
                NotificationsProcessedCount++;
                AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                 (MessagesProcessedCount + 1);
                AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) /
                                             (MessagesProcessedCount + 1);
                MessagesProcessedCount++;
                yield return(encoded);
            }
        }
Exemple #13
0
 /// <summary>
 /// Perform event to message encoding
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public IEnumerable <NetworkMessageModel> EncodeAsJson(DataSetMessageModel message)
 {
     foreach (var notification in message.Notifications)
     {
         using (var writer = new StringWriter()) {
             var value = new MonitoredItemMessage {
                 MessageContentMask = (message.Writer?.MessageSettings?
                                       .DataSetMessageContentMask).ToMonitoredItemMessageMask(
                     message.Writer?.DataSetFieldContentMask),
                 ApplicationUri  = message.ApplicationUri,
                 EndpointUrl     = message.EndpointUrl,
                 ExtensionFields = message.Writer?.DataSet?.ExtensionFields,
                 NodeId          = notification.NodeId.ToExpandedNodeId(message.ServiceMessageContext.NamespaceUris),
                 Timestamp       = message.TimeStamp ?? DateTime.UtcNow,
                 Value           = notification.Value,
                 DisplayName     = notification.DisplayName
             };
             using (var encoder = new JsonEncoderEx(writer, message.ServiceMessageContext)
             {
                 UseAdvancedEncoding = true,
                 UseUriEncoding = true,
                 UseReversibleEncoding = false
             }){
                 value.Encode(encoder);
             }
             var encoded = new NetworkMessageModel {
                 Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                 ContentEncoding = "utf-8",
                 Timestamp       = DateTime.UtcNow,
                 ContentType     = ContentMimeType.UaLegacyPublisher,
                 MessageId       = message.SequenceNumber.ToString(),
                 MessageSchema   = MessageSchemaTypes.MonitoredItemMessageJson
             };
             yield return(encoded);
         }
     }
 }
        /// <summary>
        /// DataSetMessage to NetworkMessage Json batched encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsJson(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            var notifications = GetNetworkMessages(messages, MessageEncoding.Json);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.First().ServiceMessageContext;
            var current         = notifications.GetEnumerator();
            var processing      = current.MoveNext();
            var messageSize     = 2; // array brackets

            maxMessageSize -= 2048;  // reserve 2k for header
            var chunk = new Collection <NetworkMessage>();

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperWriter  = new StringWriter();
                    var helperEncoder = new JsonEncoderEx(helperWriter, encodingContext)
                    {
                        UseAdvancedEncoding   = true,
                        UseUriEncoding        = true,
                        UseReversibleEncoding = false
                    };
                    notification.Encode(helperEncoder);
                    helperEncoder.Close();
                    var notificationSize = Encoding.UTF8.GetByteCount(helperWriter.ToString());
                    if (notificationSize > maxMessageSize)
                    {
                        // we cannot handle this notification. Drop it.
                        // TODO Trace
                        NotificationsDroppedCount++;
                        processing = current.MoveNext();
                    }
                    else
                    {
                        messageCompleted = maxMessageSize < (messageSize + notificationSize);
                        if (!messageCompleted)
                        {
                            NotificationsProcessedCount++;
                            chunk.Add(notification);
                            processing   = current.MoveNext();
                            messageSize += notificationSize + (processing ? 1 : 0);
                        }
                    }
                }
                if (!processing || messageCompleted)
                {
                    var writer  = new StringWriter();
                    var encoder = new JsonEncoderEx(writer, encodingContext,
                                                    JsonEncoderEx.JsonEncoding.Array)
                    {
                        UseAdvancedEncoding   = true,
                        UseUriEncoding        = true,
                        UseReversibleEncoding = false
                    };
                    foreach (var element in chunk)
                    {
                        encoder.WriteEncodeable(null, element);
                    }
                    encoder.Close();
                    var encoded = new NetworkMessageModel {
                        Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                        ContentEncoding = "utf-8",
                        Timestamp       = DateTime.UtcNow,
                        ContentType     = ContentMimeType.UaJson,
                        MessageSchema   = MessageSchemaTypes.NetworkMessageJson
                    };
                    AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                     (MessagesProcessedCount + 1);
                    AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount +
                                                  chunk.Count) / (MessagesProcessedCount + 1);
                    MessagesProcessedCount++;
                    chunk.Clear();
                    messageSize = 2;
                    yield return(encoded);
                }
            }
        }
        /// <summary>
        /// DataSetMessage to NetworkMessage binary batched encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.First().ServiceMessageContext;
            var current         = notifications.GetEnumerator();
            var processing      = current.MoveNext();
            var messageSize     = 4; // array length size

            maxMessageSize -= 2048;  // reserve 2k for header
            var chunk = new Collection <NetworkMessage>();

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperEncoder = new BinaryEncoder(encodingContext);
                    helperEncoder.WriteEncodeable(null, notification);
                    var notificationSize = helperEncoder.CloseAndReturnBuffer().Length;
                    if (notificationSize > maxMessageSize)
                    {
                        // we cannot handle this notification. Drop it.
                        // TODO Trace
                        NotificationsDroppedCount++;
                        processing = current.MoveNext();
                    }
                    else
                    {
                        messageCompleted = maxMessageSize < (messageSize + notificationSize);

                        if (!messageCompleted)
                        {
                            chunk.Add(notification);
                            NotificationsProcessedCount++;
                            processing   = current.MoveNext();
                            messageSize += notificationSize;
                        }
                    }
                }
                if (!processing || messageCompleted)
                {
                    var encoder = new BinaryEncoder(encodingContext);
                    encoder.WriteBoolean(null, true); // is Batch
                    encoder.WriteEncodeableArray(null, chunk);
                    var encoded = new NetworkMessageModel {
                        Body          = encoder.CloseAndReturnBuffer(),
                        Timestamp     = DateTime.UtcNow,
                        ContentType   = ContentMimeType.Uadp,
                        MessageSchema = MessageSchemaTypes.NetworkMessageUadp
                    };
                    AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                     (MessagesProcessedCount + 1);
                    AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount +
                                                  chunk.Count) / (MessagesProcessedCount + 1);
                    MessagesProcessedCount++;
                    chunk.Clear();
                    messageSize = 4;
                    yield return(encoded);
                }
            }
        }
        /// <summary>
        /// DataSetMessage to NetworkMessage Json batched encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsJson(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetNetworkMessages(messages, MessageEncoding.Json, encodingContext);

            if (!notifications.Any())
            {
                yield break;
            }
            var routingInfo             = messages.FirstOrDefault(m => m?.WriterGroup != null)?.WriterGroup.WriterGroupId;
            var current                 = notifications.GetEnumerator();
            var processing              = current.MoveNext();
            var messageSize             = 2; // array brackets
            var chunk                   = new Collection <NetworkMessage>();
            int notificationsPerMessage = 0;

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperWriter  = new StringWriter();
                    var helperEncoder = new JsonEncoderEx(helperWriter, encodingContext)
                    {
                        UseAdvancedEncoding   = true,
                        UseUriEncoding        = true,
                        UseReversibleEncoding = false
                    };
                    notification.Encode(helperEncoder);
                    helperEncoder.Close();
                    var notificationSize     = Encoding.UTF8.GetByteCount(helperWriter.ToString());
                    var notificationsInBatch = notification.Messages.Sum(m => m.Payload.Count);
                    if (notificationSize > maxMessageSize)
                    {
                        // Message too large, drop it.
                        NotificationsDroppedCount += (uint)notificationsInBatch;
                        _logger.Warning("Message too large, dropped {notificationsInBatch} values", notificationsInBatch);
                        processing = current.MoveNext();
                    }
                    else
                    {
                        messageCompleted = maxMessageSize < (messageSize + notificationSize);
                        if (!messageCompleted)
                        {
                            chunk.Add(notification);
                            NotificationsProcessedCount += (uint)notificationsInBatch;
                            notificationsPerMessage     += notificationsInBatch;
                            processing   = current.MoveNext();
                            messageSize += notificationSize + (processing ? 1 : 0);
                        }
                    }
                }
                if (messageCompleted || (!processing && chunk.Count > 0))
                {
                    var writer  = new StringWriter();
                    var encoder = new JsonEncoderEx(writer, encodingContext,
                                                    JsonEncoderEx.JsonEncoding.Array)
                    {
                        UseAdvancedEncoding   = true,
                        UseUriEncoding        = true,
                        UseReversibleEncoding = false
                    };
                    foreach (var element in chunk)
                    {
                        encoder.WriteEncodeable(null, element);
                    }
                    encoder.Close();
                    var encoded = new NetworkMessageModel {
                        Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                        ContentEncoding = "utf-8",
                        Timestamp       = DateTime.UtcNow,
                        ContentType     = ContentMimeType.Json,
                        MessageSchema   = MessageSchemaTypes.NetworkMessageJson,
                        RoutingInfo     = _enableRoutingInfo ? routingInfo : null,
                    };
                    AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                     (MessagesProcessedCount + 1);
                    AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount +
                                                  notificationsPerMessage) / (MessagesProcessedCount + 1);
                    MessagesProcessedCount++;
                    chunk.Clear();
                    messageSize             = 2;
                    notificationsPerMessage = 0;
                    yield return(encoded);
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// Perform DataSetMessageModel to NetworkMessageModel batch using Json encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsJson(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Json);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            var encodingContext = messages.First().ServiceMessageContext;
            var current         = notifications.GetEnumerator();
            var processing      = current.MoveNext();
            var messageSize     = 2; // array brackets

            maxMessageSize -= 2048;  // reserve 2k for header
            var chunk = new Collection <MonitoredItemMessage>();

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperWriter  = new StringWriter();
                    var helperEncoder = new JsonEncoderEx(helperWriter, encodingContext)
                    {
                        UseAdvancedEncoding   = true,
                        UseUriEncoding        = true,
                        UseReversibleEncoding = false
                    };
                    notification.Encode(helperEncoder);
                    helperEncoder.Close();

                    var notificationSize = Encoding.UTF8.GetByteCount(helperWriter.ToString());
                    messageCompleted = maxMessageSize < (messageSize + notificationSize);

                    if (!messageCompleted)
                    {
                        chunk.Add(notification);
                        processing   = current.MoveNext();
                        messageSize += notificationSize + (processing ? 1 : 0);
                    }
                }
                if (!processing || messageCompleted)
                {
                    var writer  = new StringWriter();
                    var encoder = new JsonEncoderEx(writer, encodingContext,
                                                    JsonEncoderEx.JsonEncoding.Array)
                    {
                        UseAdvancedEncoding   = true,
                        UseUriEncoding        = true,
                        UseReversibleEncoding = false
                    };
                    foreach (var element in chunk)
                    {
                        encoder.WriteEncodeable(null, element);
                    }
                    encoder.Close();
                    chunk.Clear();
                    messageSize = 2;  // array brackets
                    var encoded = new NetworkMessageModel {
                        Body            = Encoding.UTF8.GetBytes(writer.ToString()),
                        ContentEncoding = "utf-8",
                        Timestamp       = DateTime.UtcNow,
                        ContentType     = ContentMimeType.UaJson,
                        MessageSchema   = MessageSchemaTypes.MonitoredItemMessageJson
                    };
                    yield return(encoded);
                }
            }
        }
Exemple #18
0
        /// <summary>
        /// DataSetMessage to NetworkMessage binary batched encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp, encodingContext);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            var current                 = notifications.GetEnumerator();
            var processing              = current.MoveNext();
            var messageSize             = 4; // array length size
            var chunk                   = new Collection <NetworkMessage>();
            int notificationsPerMessage = 0;

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperEncoder = new BinaryEncoder(encodingContext);
                    helperEncoder.WriteEncodeable(null, notification);
                    var notificationSize = helperEncoder.CloseAndReturnBuffer().Length;
                    notificationsPerMessage = notification.Messages.Sum(m => m.Payload.Count);
                    if (notificationSize > maxMessageSize)
                    {
                        // Message too large, drop it.
                        NotificationsDroppedCount += (uint)notificationsPerMessage;
                        _logger.Warning("Message too large, dropped {notificationsPerMessage} values");
                        processing = current.MoveNext();
                    }
                    else
                    {
                        messageCompleted = maxMessageSize < (messageSize + notificationSize);
                        if (!messageCompleted)
                        {
                            chunk.Add(notification);
                            NotificationsProcessedCount += (ulong)notificationsPerMessage;
                            processing   = current.MoveNext();
                            messageSize += notificationSize;
                        }
                    }
                }
                if (!processing || messageCompleted)
                {
                    var encoder = new BinaryEncoder(encodingContext);
                    encoder.WriteBoolean(null, true); // is Batch
                    encoder.WriteEncodeableArray(null, chunk);
                    var encoded = new NetworkMessageModel {
                        Body          = encoder.CloseAndReturnBuffer(),
                        Timestamp     = DateTime.UtcNow,
                        ContentType   = ContentMimeType.Uadp,
                        MessageSchema = MessageSchemaTypes.NetworkMessageUadp
                    };
                    AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                     (MessagesProcessedCount + 1);
                    AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount +
                                                  notificationsPerMessage) / (MessagesProcessedCount + 1);
                    MessagesProcessedCount++;
                    chunk.Clear();
                    messageSize             = 4;
                    notificationsPerMessage = 0;
                    yield return(encoded);
                }
            }
        }