Files
Martijn Scheepers 5c3ccb4677 async iot listener
2023-11-22 14:06:08 +01:00

165 lines
6.0 KiB
C#

using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace UCS.IOTServer
{
public static class Server
{
private static readonly NLog.Logger Errorlog = NLog.LogManager.GetLogger("IOTServer");
public static IPAddress ServerIPAddress { get; private set; }
public static event EventHandler<string> RxLogEventFired;
public static event EventHandler<IOTMessage> ReceiveEventFiredIOTServerObject;
private static bool _Stopping = false;
public static void Start(int port)
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
foreach (var iPAddress in ipHostInfo.AddressList)
{
if (iPAddress.AddressFamily.Equals(AddressFamily.InterNetwork))
{
ServerIPAddress = iPAddress;
break;
}
}
Errorlog.Info($"IOTServer wordt gestart - {ServerIPAddress}:{port}");
try
{
//run command to add port
//netsh http add urlacl url="http://+:5050/" user=everyone
//netsh http delete urlacl url="http://+:5050"
Task.Run(async () =>
{
using (HttpListener listener = new HttpListener())
{
listener.Prefixes.Add("http://+:" + port.ToString() + "/");
listener.Start();
while (!_Stopping)
{
HttpListenerContext context = await listener.GetContextAsync();
//Debug.WriteLine("Client connected");
await ParseMessage(context);
}
listener.Stop();
listener.Close();
}
});
}
catch (Exception ex)
{
Errorlog.Error(ex, "IOTServer start error");
Errorlog.Error("Access denied:run cmd \"netsh http add urlacl url=\"http://+:5050/\" user=everyone\"");
throw;
}
}
public static void Stop()
{
Errorlog.Info("IOTServer wordt gestopt");
_Stopping = true;
}
private static async Task ParseMessage(HttpListenerContext context)
{
try
{
HttpListenerRequest request = context.Request;
if (request.HttpMethod == "GET")
{
//PRTG message
RxLogEventFired?.Invoke(null, request.RawUrl);
PrtgMessage prtgMessage = new PrtgMessage(request.RawUrl);
if (prtgMessage.PrtgData == null)
{
await SendFailed(context.Response);
Errorlog.Error($"prtgmessage is null: {request.RawUrl}");
return;
}
IOTMessage iOTMessage = new IOTMessage(prtgMessage);
ReceiveEventFiredIOTServerObject?.Invoke(null, iOTMessage);
}
if (request.HttpMethod == "POST")
{
//Nodered message
using (var reader = new StreamReader(request.InputStream, request.ContentEncoding))
{
string jsondata = reader.ReadToEnd();
RxLogEventFired?.Invoke(null, jsondata);
try
{
NoderedMessage noderedMessage = JsonConvert.DeserializeObject<NoderedMessage>(jsondata);
if (noderedMessage == null)
{
Errorlog.Error($"Noderedmesage is null: {jsondata}");
await SendFailed(context.Response);
return;
}
IOTMessage iOTMessage = new IOTMessage(noderedMessage);
ReceiveEventFiredIOTServerObject?.Invoke(null, iOTMessage);
}
catch (Exception ex)
{
Errorlog.Error(ex, $"Nodered json Deserialize error - {ex.Message}");
Errorlog.Error(jsondata);
await SendFailed(context.Response);
return;
}
}
}
await SendOk(context.Response);
}
catch (Exception ex)
{
Errorlog.Error(ex, $"ListenerCallback Failed {ex.Message}");
}
}
private static async Task SendOk(HttpListenerResponse response)
{
try
{
byte[] buffer = Encoding.UTF8.GetBytes("OK");
response.ContentLength64 = buffer.Length;
response.StatusCode = 200;
await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
response.OutputStream.Close();
}
catch (Exception ex)
{
Errorlog.Error(ex, $"SendOk Failed {ex.Message}");
}
}
private static async Task SendFailed(HttpListenerResponse response)
{
try
{
byte[] buffer = Encoding.UTF8.GetBytes("failed");
response.ContentLength64 = buffer.Length;
response.StatusCode = 400;
await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
response.OutputStream.Close();
}
catch (Exception ex)
{
Errorlog.Error(ex, $"SendFailed Failed {ex.Message}");
}
}
}
}