Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PipeEventSink.cs
1using System;
3using System.IO;
4using System.IO.Pipes;
5using System.Security.Principal;
6using System.Text;
7using System.Threading.Tasks;
10
11namespace Waher.Events.Pipe
12{
18 public delegate NamedPipeClientStream NamedPipeClientStreamFactory(string Name);
19
23 public class PipeEventSink : EventSink
24 {
25 private readonly LinkedList<byte[]> pipeQueue = new LinkedList<byte[]>();
26 private readonly NamedPipeClientStreamFactory pipeStreamFactory;
27 private readonly string pipeName;
28 private NamedPipeClientStream pipe;
29 private bool writing = false;
30
36 public PipeEventSink(string ObjectId, string PipeName)
37 : this(ObjectId, PipeName, DefaultFactory)
38 {
39 }
40
47 public PipeEventSink(string ObjectId, string PipeName, NamedPipeClientStreamFactory StreamFactory)
48 : base(ObjectId)
49 {
50 this.pipeStreamFactory = StreamFactory;
51 this.pipe = null;
52 this.pipeName = PipeName;
53 }
54
55 private static NamedPipeClientStream DefaultFactory(string Name)
56 {
57 return new NamedPipeClientStream(".", Name, PipeDirection.Out, PipeOptions.Asynchronous,
58 TokenImpersonationLevel.Anonymous, HandleInheritability.None);
59 }
60
64 public NamedPipeClientStream Pipe => this.pipe;
65
69 public override Task DisposeAsync()
70 {
71 if (!(this.pipe is null))
72 {
73 this.pipe?.Dispose();
74 this.pipe = null;
75 }
76
77 return base.DisposeAsync();
78 }
79
84 public override Task Queue(Event Event)
85 {
86 return this.Queue(Event.ToXML(), false);
87 }
88
93 public Task Queue(string Xml)
94 {
95 return this.Queue(Xml, true);
96 }
97
104 private async Task Queue(string Xml, bool ValidateXml)
105 {
106 if (ValidateXml && !XML.IsValidXml(Xml))
107 throw new ArgumentException("Invalid XML.", nameof(Xml));
108
109 try
110 {
111 byte[] Bin = Encoding.UTF8.GetBytes(Xml);
112
113 lock (this.pipeQueue)
114 {
115 if (this.writing)
116 {
117 this.pipeQueue.AddLast(Bin);
118 return;
119 }
120 else
121 this.writing = true;
122 }
123
124 if (!(this.pipe is null) && !this.pipe.IsConnected)
125 {
126 this.pipe.Dispose();
127 this.pipe = null;
128 }
129
130 if (this.pipe is null)
131 {
132 this.pipe = this.pipeStreamFactory(this.pipeName);
133 await this.BeforeConnect.Raise(this, EventArgs.Empty);
134 await this.pipe.ConnectAsync(5000);
135 await this.AfterConnect.Raise(this, EventArgs.Empty);
136 }
137
138 while (!(Bin is null))
139 {
140 await this.pipe.WriteAsync(Bin, 0, Bin.Length);
141
142 lock (this.pipeQueue)
143 {
144 if (this.pipeQueue.First is null)
145 {
146 this.writing = false;
147 Bin = null;
148 }
149 else
150 {
151 Bin = this.pipeQueue.First.Value;
152 this.pipeQueue.RemoveFirst();
153 }
154 }
155 }
156 }
157 catch (TimeoutException)
158 {
159 this.EmptyPipeQueue();
160 }
161 catch (IOException)
162 {
163 this.EmptyPipeQueue();
164 }
165 catch (Exception ex)
166 {
167 this.EmptyPipeQueue();
168 Log.Exception(ex);
169 }
170 }
171
172 private void EmptyPipeQueue()
173 {
174 lock (this.pipeQueue)
175 {
176 this.pipeQueue.Clear();
177 this.writing = false;
178 }
179 }
180
185
190 }
191}
Helps with common XML-related tasks.
Definition: XML.cs:21
static bool IsValidXml(string Xml)
Checks if a string is valid XML
Definition: XML.cs:1397
Class representing an event.
Definition: Event.cs:11
Base class for event sinks.
Definition: EventSink.cs:9
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1657
Writes logged events to an operating system pipe, for inter-process communication.
PipeEventSink(string ObjectId, string PipeName)
Writes logged events to an operating system pipe, for inter-process communication.
EventHandlerAsync AfterConnect
Raised after connecting to the pipe stream
override Task Queue(Event Event)
Queues an event to be output.
PipeEventSink(string ObjectId, string PipeName, NamedPipeClientStreamFactory StreamFactory)
Writes logged events to an operating system pipe, for inter-process communication.
NamedPipeClientStream Pipe
Pipe object.
EventHandlerAsync BeforeConnect
Raised before connecting to the pipe stream.
override Task DisposeAsync()
IDisposableAsync.DisposeAsync()
Task Queue(string Xml)
Queues XML-encoded information to be output.
delegate NamedPipeClientStream NamedPipeClientStreamFactory(string Name)
Delegate for methods that create object instances of NamedPipeClientStream.
delegate Task EventHandlerAsync(object Sender, EventArgs e)
Asynchronous version of EventArgs.