using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Node;
//***This is based on native .NET core HTTP services. Arcs and Nodes communicate via POST requests through proxies***
namespace a2_model_arcs_grpc
{
class Program
{
static void Main(string[] args)
{
foreach (var arg in args)
{
var nodeExecPath = arg;
// This could be improved by reading input config file from program argument.
// It is currently being hardcoded here since we only allow one argument for this program (stated in assignment description).
var script = $”start \”node_1\” cmd /k {nodeExecPath} 1 2 3 4 timeout 1\n” +
$”start \”node_2\” cmd /k {nodeExecPath} 2 1 3 timeout 1\n” +
$”start \”node_3\” cmd /k {nodeExecPath} 4 3 1 timeout 1\n” +
$”start \”node_4\” cmd /k {nodeExecPath} 3 1 2 4 timeout 1\n”;
File.WriteAllText(@”./start.bat”, script);
Process.Start(@”./start.bat”);
// This could be improved along with the starting script generation.
// It is currently being hardcoded here since we only allow one argument for this program (stated in assignment description).
var nodes = new int[] { 1, 2, 3, 4 };
var delays = new Dictionary<(int, int), int>{
{ (1,3), 10 },
{ (1,4), 10 },
{ (2,1), 10 },
{ (3,2), 10 },
{ (4,3), 10 }
};
int MaxDelay = 10;
int MessageCount = 0;
// Arcs listening at 8080
HttpListener listener = new HttpListener();
var address = $”http://localhost:8080/”;
listener.Prefixes.Add(address);
listener.Start();
Console.WriteLine($”Arcs Listening at {address}…”);
// ping nodes
foreach (var n in nodes)
{
var ping = new Message(0, 0, 0, n, 0, 0);
var pingTask = Common.PostMessage(ping);
pingTask.Wait();
}
// post initiator
var m0 = new Message(0, 2, 0, 1, 1, 0);
var _ = Common.PostMessage(m0);
while (true)
{
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
string content;
using (Stream receiveStream = request.InputStream)
{
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
content = readStream.ReadToEnd();
}
}
// Console.WriteLine($”Recived request for {request.Url}”);
var message = JsonSerializer.Deserialize
message.time += delays.GetValueOrDefault((message.@from, message.to), 1);
MessageCount++;
if (message.to == 0)
{
Console.WriteLine();
Console.WriteLine($” {message.time,3} {message.time / MaxDelay,3} {MessageCount,3} {message.pay,3}”);
// Stop nodes
foreach (var n in nodes)
{
var stop = new Message(message.time, 3, 0, n, 0, 0);
var stopTask = Common.PostMessage(stop);
stopTask.Wait();
}
break;
}
Common.Print(message);
_ = Common.PostMessage(message);
}
listener.Stop();
break; // Arcs takes one command line argument = the path to run the Node
}
}
}
}