private static IServerPM ConnectToServer(string serverID, RemotingAddress serverRA) { if (!serverList.Exists(x => x.Item2 == serverRA)) { if (serverList.Exists(x => x.Item1 == serverID)) { throw new ApplicationException($"Server with ID '{serverID}' already exists."); } IServerPM server = (IServerPM)Activator.GetObject(typeof(IServerPM), serverRA.ToString()); if (server == null) { throw new ApplicationException("Could not locate Server: " + serverRA.ToString()); } serverList.Add(new Tuple <string, RemotingAddress, IServerPM>(serverID, serverRA, server)); //Add server to replication servers list remoteServerList.Add(new Tuple <string, RemotingAddress>(serverID, serverRA)); return(server); } else { throw new ApplicationException("Already connected to server: " + serverRA.ToString()); } }
public OSDMap PackRegionInfoData() { OSDMap args = new OSDMap(); args["region_id"] = OSD.FromUUID(RegionID); if ((RegionName != null) && !RegionName.Equals("")) { args["region_name"] = OSD.FromString(RegionName); } args["external_host_name"] = OSD.FromString(ExternalHostName); args["http_port"] = OSD.FromString(HttpPort.ToString()); args["server_uri"] = OSD.FromString(ServerURI); args["region_xloc"] = OSD.FromString(RegionLocX.ToString()); args["region_yloc"] = OSD.FromString(RegionLocY.ToString()); args["internal_ep_address"] = OSD.FromString(InternalEndPoint.Address.ToString()); args["internal_ep_port"] = OSD.FromString(InternalEndPoint.Port.ToString()); if ((RemotingAddress != null) && !RemotingAddress.Equals("")) { args["remoting_address"] = OSD.FromString(RemotingAddress); } args["remoting_port"] = OSD.FromString(RemotingPort.ToString()); args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports); if ((proxyUrl != null) && !proxyUrl.Equals("")) { args["proxy_url"] = OSD.FromString(proxyUrl); } return(args); }
public void RegisterServerReplica(string serverID, RemotingAddress serverRA) { IServerC newServerChannel = (IServerC)Activator.GetObject(typeof(IServerC), serverRA.ToString()); Client.serverReplicasList.Add(newServerChannel); MessageBox.Show("Client: " + Client.Username + " Registered Server: " + serverRA.ToString()); }
public PCSService() { string PMAddress = CallContext.GetData("ClientIPAddress").ToString(); RemotingAddress PMRA = new RemotingAddress(PMAddress, 10001, "MSPM"); PM = (IPM)Activator.GetObject(typeof(IPM), PMRA.ToString()); Utilities.WriteDebug($"PCSServices constructed by {PMAddress}."); }
static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (args.Length < 3 || args.Length > 4) { string error = "This program must take at least 3 arguments. " + "client name, client remoting address, and server remoting address. " + "Optionally a 4th argument, the script filename."; MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Username = args[0]; ClientRA = RemotingAddress.FromString(args[1]); ServerRA = RemotingAddress.FromString(args[2]); ListenClient(ClientRA.port, ClientRA.channel); try { ConnectToServer(ServerRA, Username, ClientRA); } catch (Exception e) { MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //https://stackoverflow.com/questions/5991249/application-exit-not-working Environment.Exit(0); } if (args.Length > 3 && args[3] != "") { string scriptFilename = args[3]; try { Parser parser = new Parser(scriptFilename); parser.Parse(); Thread scriptThread = new Thread(parser.ExecCommands); scriptThread.Start(); } catch (ParserException pe) { MessageBox.Show(pe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } mainForm = new MainForm(); Application.Run(mainForm); }
public void InformClientJoinedMeeting(MeetingProposal mp, string clientName, RemotingAddress clientRA, List <Slot> slots) { foreach (MeetingProposal meeting in Server.meetingPropList) { if (meeting.Topic == mp.Topic) { if (!meeting.ClientsJoined.ContainsKey(clientName)) { Console.WriteLine("Inform replicas that client: " + clientName + " joined meeting: " + mp.Topic); meeting.AddClientToMeeting(clientName, clientRA, slots); } } } }
public static void InformAllServersOfJoinedMeeting(MeetingProposal mp, string clientName, RemotingAddress clientRA, List <Slot> slots) { foreach (var s in otherServers) { try { s.ServerChannel.InformClientJoinedMeeting(mp, clientName, clientRA, slots); } catch (System.Net.Sockets.SocketException) { Console.WriteLine("Server: " + s.ServerID + " is down!"); } } }
public static void ConnectToServer(RemotingAddress serverRA, string clientName, RemotingAddress clientRA) { Username = clientName; server = (IServerC)Activator.GetObject(typeof(IServerC), serverRA.ToString()); try { server.RegisterClient(clientName, clientRA); } catch (System.Net.Sockets.SocketException) { MessageBox.Show("Lost connection to the server.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private static IPCS ConnectToPCS(RemotingAddress PCSRemotingAddress) { if (!PCSList.Exists(x => x.Item1 == PCSRemotingAddress)) { IPCS pcs = (IPCS)Activator.GetObject(typeof(IPCS), PCSRemotingAddress.ToString()); if (pcs == null) { throw new ApplicationException("Could not locate PCS: " + PCSRemotingAddress.ToString()); } PCSList.Add(new Tuple <RemotingAddress, IPCS>(PCSRemotingAddress, pcs)); return(pcs); } else { return(PCSList.Find(x => x.Item1 == PCSRemotingAddress).Item2); } }
public static void CreateServer(string serverID, RemotingAddress serverRA, uint maxFaults, uint minDelay, uint maxDelay) { if (serverList.Exists(x => x.Item1 == serverID)) { throw new ApplicationException($"Server with ID '{serverID}' already exists."); } RemotingAddress pcsRA = new RemotingAddress(serverRA.address, PCSPort, PCSChannel); IPCS pcs = GetPCS(pcsRA); try { pcs.StartServer(serverID, serverRA, maxFaults, minDelay, maxDelay); } catch (System.Net.Sockets.SocketException) { MessageBox.Show($"Connection with PCS on remoting address '{pcsRA.ToString()}' was lost.\n" + "If the PCS has been restarted you may try again."); Program.RemovePCSFromList(pcsRA); return; } IServerPM server = ConnectToServer(serverID, serverRA); //Replication //Inform new server of all existing servers server.SendExistingServersList(remoteServerList); //Inform all existing servers of new server foreach (Tuple <string, RemotingAddress, IServerPM> serv in serverList) { serv.Item3.BroadcastNewServer(new Tuple <string, RemotingAddress>(serverID, serverRA)); } // Fill location list if (serverList.Count == 1) { mainForm.manageServersPage.FillLocationCb(server.GetLocationsPM()); } mainForm.manageServersPage.AddServerToList(serverID); }
public void InformNewClient(string newClientUsername, RemotingAddress newClientRA) { bool clientExists = false; foreach (Client c in Server.clients) { if (c.Username == newClientUsername) { clientExists = true; } } if (!clientExists) { IClient cliChannel = (IClient)Activator.GetObject(typeof(IClient), newClientRA.ToString()); Client newClient = new Client(cliChannel, newClientUsername, newClientRA); Server.clients.Add(newClient); cliChannel.RegisterServerReplica(Server.serverID, Server.serverRAForClients); } }
public static void CreateClient(string username, RemotingAddress clientRA, RemotingAddress serverRA, string scriptFile) { RemotingAddress pcsRA = new RemotingAddress(serverRA.address, PCSPort, PCSChannel); IPCS pcs = GetPCS(pcsRA); try { pcs.StartClient(username, clientRA, serverRA, scriptFile); } catch (System.Net.Sockets.SocketException) { MessageBox.Show($"Connection with PCS on remoting address '{pcsRA.ToString()}' was lost.\n" + "If the PCS has been restarted you may try again."); Program.RemovePCSFromList(pcsRA); return; } }
private void joinButton_Click(object sender, EventArgs e) { if (myClient != null) { return; } //TODO hardcoded for now clientRA = RemotingAddress.FromString("tcp://localhost:65001/MSClient"); //TODO hardcoded for now serverRA = RemotingAddress.FromString("tcp://localhost:65000/MSServer"); myClient.listenClient(clientRA.port, clientRA.channel); string clientName = nameTextBox.Text; if (clientName == null) { return; } myClient.connectToServer(serverRA.ToString(), clientName, clientRA.ToString()); }
public void RegisterClient(string username, RemotingAddress clientRA) { Server.freezeHandle.WaitOne(); // For Freeze command this.Delay(); // For induced delay if (username == null || username == "") { throw new ApplicationException($"Username cannot be empty!"); } if (clientRA == null || clientRA.address == null || clientRA.address == "") { throw new ApplicationException($"Your address cannot be empty!"); } if (clientRA.channel == null || clientRA.channel == "") { throw new ApplicationException($"Your channel cannot be empty!"); } if (Server.clients.Where(c => c.Username == username).Count() > 0) { throw new ApplicationException($"Someone with username '{username}' is already connected."); } IClient newClientChannel = (IClient)Activator.GetObject(typeof(IClient), clientRA.ToString()); Client newClient = new Client(newClientChannel, username, clientRA); Server.clients.Add(newClient); //Send new clientToAllOtherServers Thread threadS = new Thread(() => Server.InformAllServersOfNewClient(newClient)); threadS.Start(); //Inforam all clients of new client Thread thread = new Thread(() => Server.InformAllClientsOfNewClient(newClient.Username)); thread.Start(); Console.WriteLine($"New client '{username}' listening at '{clientRA}'"); }
public void StartServer(string serverId, RemotingAddress serverRA, uint maxFaults, uint minDelay, uint maxDelay) { if (Program.serverProcesses.ContainsKey(serverId)) { throw new RemotingException($"PCS: Server with ID '{ serverId }' already exists."); } var procPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory() + @"\..\..\..\Server\bin\Debug\Server.exe")); Console.WriteLine($"Starting server:\n\t" + $"ID: {serverId}\n\t" + $"URL: {serverRA.ToString()}\n\t" + $"Max Faults: {maxFaults}\n\t" + $"Min Delay: {minDelay}\n\t" + $"Max Delay: {maxDelay}\n\t" + $"Proc. path: {procPath}"); Process server = RunProcess(procPath, $"{serverId} {serverRA.ToString()} {maxFaults} {minDelay} {maxDelay}"); server.Exited += new EventHandler(delegate(Object o, EventArgs a) { Program.serverProcesses.Remove(serverId); Console.WriteLine($"Server '{serverId}' has exited."); try { PM.InformServerExited(serverId); } catch (Exception ex) { Utilities.WriteError($"Error informing PM that server exited: {ex.Message}."); } }); Program.serverProcesses.Add(serverId, server); }
public void StartClient(string username, RemotingAddress clientRA, RemotingAddress serverRA, string scriptFile) { if (Program.clientProcesses.ContainsKey(username)) { throw new RemotingException($"PCS: Client with username '{ username }' already exists."); } var procPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory() + @"\..\..\..\Client\bin\Debug\Client.exe")); Console.WriteLine($"Starting client:\n\t" + $"Username: {username}\n\t" + $"Client URL: {clientRA.ToString()}\n\t" + $"Server URL: {serverRA.ToString()}\n\t" + $"Script path: {scriptFile}\n\t" + $"Proc. path: {procPath}"); Process client = RunProcess(procPath, $"{username} {clientRA.ToString()} {serverRA.ToString()} {scriptFile}"); client.Exited += new EventHandler(delegate(Object o, EventArgs a) { Program.clientProcesses.Remove(username); Console.WriteLine($"Client '{username}' has exited."); try { PM.InformClientExited(username); } catch (Exception ex) { Utilities.WriteError($"Error informing PM that client exited: {ex.Message}."); } }); Program.clientProcesses.Add(username, client); }
static void Main(string[] args) { if (args.Length != 5) { string err = "This program must take 6+ arguments. " + "server id, server remoting address, max. faults, " + "min delay, max delay, number of known servers, known servers addresses."; Utilities.WriteError(err); return; } serverID = args[0]; serverRAForClients = RemotingAddress.FromString(args[1]); maxFaults = Convert.ToInt32(args[2]); minDelay = Convert.ToInt32(args[3]); maxDelay = Convert.ToInt32(args[4]); /* TODO * serverRAForServers = RemotingAddress.FromString(args[1]); * serverRAForServers.channel += "Repl"; * otherServers = Convert.ToInt32(args[5]); * * for (int nOtherServer = 0; nOtherServer < otherServers; nOtherServer++) * { * RemotingAddress otherServer = RemotingAddress.FromString(args[6 + nOtherServer]); * otherServerList.Add(otherServer, (IServerS)Activator.GetObject(typeof(IServerC), otherServer.ToString())); * } */ string error = ""; if (maxFaults < 0) { error = "Max. faults cannot be less than 0."; } else if (minDelay < 0) { error = "Min. delay cannot be less than 0."; } else if (maxDelay < 0) { error = "Max. delay cannot be less than 0."; } else if (minDelay > maxDelay) { error = "Min. delay cannot be bigger than max. delay."; } if (error != "") { Utilities.WriteError(error); return; } GenerateLocationRooms(); ListenServer(); //TODO //Connect to PM to receive list of Servers //connectPM(); //Connect to each of those Server and add it to the otherServers list //connectToAll //Everytime a server connects to another servers, that server checks if the //incoming server already is on his list, if it doesnt, connect to it (like server and client comm) Console.WriteLine("Press <enter> to terminate server..."); System.Console.ReadLine(); }
private static IPCS GetPCS(RemotingAddress PCSRA) { return(ConnectToPCS(PCSRA)); }
public static IServerPM GetServer(RemotingAddress serverRA) { return(serverList.Find(x => x.Item2 == serverRA).Item3); }
private static void RemovePCSFromList(RemotingAddress pcsRA) { PCSList.RemoveAll(p => p.Item1 == pcsRA); }
public void CreateMeeting(string coordinatorUser, RemotingAddress coordinatorRA, string topic, uint minAttendees, List <Slot> slots, List <string> invitees) { Server.freezeHandle.WaitOne(); // For Freeze command this.Delay(); // For induced delay #region Validate arguments (topic exists, locations exist, invitees exist...) if (topic == "") { throw new ApplicationException("Must add a topic!"); } if (coordinatorUser == "") { throw new ApplicationException("You do not have a username!"); } if (coordinatorRA == null) { throw new ApplicationException("You did not provide a Remoting Address!"); } if (minAttendees == 0) { throw new ApplicationException("Minimum attendees must be higher than 0!"); } if (slots.Count == 0) { throw new ApplicationException("Must add slots to the meeting!"); } // Find repeated slots var myListSlots = new List <Slot>(); var duplicateSlots = new List <Slot>(); foreach (var s in slots) { if (!myListSlots.Contains(s)) { myListSlots.Add(s); } else { duplicateSlots.Add(s); } } if (duplicateSlots.Count > 0) { throw new ApplicationException("You have repeated slots."); } // Find repeated invitees var myListInvitees = new List <string>(); var duplicateInvitees = new List <string>(); foreach (var s in invitees) { if (!myListInvitees.Contains(s)) { myListInvitees.Add(s); } else { duplicateInvitees.Add(s); } } if (duplicateInvitees.Count > 0) { throw new ApplicationException("You have repeated invitees."); } // Check if all invitees exist foreach (string invitee in invitees) { if (Server.clients.Where(i => i.Username == invitee).Count() == 0) { throw new ApplicationException($"Invitee '{invitee}' does not exist or is not connected."); } } // Check if locations exist foreach (Slot s in slots) { if (!Server.locationRooms.ContainsKey(s.location)) { throw new ApplicationException($"Location '{s.location}' does not exist in the server."); } } // Check if a meeting with this topic does not exist already foreach (MeetingProposal mp2 in Server.meetingPropList) { if (mp2.Topic == topic) { throw new ApplicationException("A meeting with this topic already exists."); } } #endregion MeetingProposal mp = new MeetingProposal(coordinatorUser, coordinatorRA, topic, minAttendees, slots, invitees); Server.meetingPropList.Add(mp); //Send new meetingToAllOtherServers Thread threadS = new Thread(() => Server.InformAllServersOfNewMeeting(mp)); threadS.Start(); //Inforam all clients Thread thread = new Thread(() => Server.InformClientsOfNewMeeting(mp)); thread.Start(); Console.WriteLine("[Server] Created meeting:" + "\n\tTopic: " + topic + "\n\tCoordinator: " + coordinatorUser + "\n\tCoordinator URL: " + coordinatorRA + "\n\tMinimum attendees: " + minAttendees); Console.WriteLine("[SERVER]: " + Server.serverID + " MeetingsList: " + Server.meetingPropList.Count); }
private void createSrvBtn_Click(object sender, EventArgs e) { bool valid = true; RemotingAddress serverRA = new RemotingAddress(); if (serverIDTb.Text == "") { valid = false; MessageBox.Show("Server ID cannot be empty.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (serverRATb.Text == "") { valid = false; MessageBox.Show("Server remoting address cannot be empty.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { try { serverRA = RemotingAddress.FromString(serverRATb.Text); } catch (ArgumentException) { valid = false; MessageBox.Show("Server remoting address is invalid.\n" + "Must be of the format: tcp://address:port/channel", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (maxFaultsNUD.Value < 0) { valid = false; MessageBox.Show("Maximum faults cannot be negative.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (minDelayNUD.Value < 0) { valid = false; MessageBox.Show("Minimum delay cannot be negative.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (maxDelayNUD.Value < 0) { valid = false; MessageBox.Show("Maximum delay cannot be negative.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (minDelayNUD.Value > maxDelayNUD.Value) { valid = false; MessageBox.Show("Minimum delay cannot be bigger than maximum delay.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (valid) { try { Program.CreateServer(serverIDTb.Text, serverRA, Convert.ToUInt16(maxFaultsNUD.Value), Convert.ToUInt16(minDelayNUD.Value), Convert.ToUInt16(maxDelayNUD.Value)); Program.mainForm.switchPage(Program.mainForm.mainPage); } catch (Exception ex) { MessageBox.Show($"Error creating server: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
public Client(IClient clientChannel, string username, RemotingAddress clientRA) { this.ClientChannel = clientChannel; this.Username = username; this.ClientRA = clientRA; }
private void createCliBtn_Click(object sender, EventArgs e) { bool valid = true; RemotingAddress serverRA = new RemotingAddress(); RemotingAddress clientRA = new RemotingAddress(); string username = usernameTb.Text.Trim(); string clientRAStr = clientRATb.Text.Trim(); string serverRAStr = serverRATb.Text.Trim(); string scriptPath = scriptPathTb.Text.Trim(); if (username == "") { valid = false; MessageBox.Show("Username cannot be empty.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (clientRAStr == "") { valid = false; MessageBox.Show("Client remoting address cannot be empty.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { try { clientRA = RemotingAddress.FromString(clientRAStr); } catch (ArgumentException) { valid = false; MessageBox.Show("Client remoting address is invalid.\n" + "Must be of the format: tcp://address:port/channel", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (serverRAStr == "") { valid = false; MessageBox.Show("Server remoting address cannot be empty.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { try { serverRA = RemotingAddress.FromString(serverRAStr); } catch (ArgumentException) { valid = false; MessageBox.Show("Server remoting address is invalid.\n" + "Must be of the format: tcp://address:port/channel", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (valid) { try { Program.CreateClient(username, clientRA, serverRA, scriptPath); Program.mainForm.switchPage(Program.mainForm.mainPage); } catch (Exception ex) { MessageBox.Show($"Error creating client: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
public OtherServer(IServerS serverChannel, string serverID, RemotingAddress serverRA) { this.ServerChannel = serverChannel; this.ServerID = serverID; this.ServerRA = serverRA; }
public void ExecCommands() { foreach (var command in commands) { MessageBox.Show("PM Will Execute... " + command[0]); if (command[0].Equals("crash", StringComparison.OrdinalIgnoreCase)) { IServerPM server = Program.GetServer(command[1]); try { server.Crash(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //return; } } else if (command[0].Equals("freeze", StringComparison.OrdinalIgnoreCase)) { IServerPM server = Program.GetServer(command[1]); try { server.Freeze(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //return; } } else if (command[0].Equals("unfreeze", StringComparison.OrdinalIgnoreCase)) { IServerPM server = Program.GetServer(command[1]); try { server.Unfreeze(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //return; } } else if (command[0].Equals("wait", StringComparison.OrdinalIgnoreCase)) { Utilities.Wait(Int32.Parse(command[1])); } else if (command[0].Equals("status", StringComparison.OrdinalIgnoreCase)) { Program.PrintStatus(); } else if (command[0].Equals("server", StringComparison.OrdinalIgnoreCase)) { try { Program.CreateServer(command[1], RemotingAddress.FromString(command[2]), Convert.ToUInt32(command[3]), Convert.ToUInt32(command[4]), Convert.ToUInt32(command[5])); } catch (Exception ex) { MessageBox.Show($"Error creating server: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //return; } } else if (command[0].Equals("client", StringComparison.OrdinalIgnoreCase)) { try { Program.CreateClient(command[1], RemotingAddress.FromString(command[2]), RemotingAddress.FromString(command[3]), command[4]); } catch (Exception ex) { MessageBox.Show($"Error creating client: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //return; } } else if (command[0].Equals("AddRoom", StringComparison.OrdinalIgnoreCase)) { if (Program.serverList.Count == 0) { MessageBox.Show($"Cannot add room '{command[3]}' because there are no servers running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); continue;//return; } try { Program.serverList[0].Item3.AddRoom(command[1], Convert.ToUInt32(command[2]), command[3]); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //return; } } foreach (string s in command) { Utilities.WriteDebug(s + " "); } Console.Write("\r\n"); //MessageBox.Show("PM Executed: " + command[0]); } }
public void JoinMeeting(string topic, string clientName, RemotingAddress clientRA, List <Slot> slots) { Server.freezeHandle.WaitOne(); // For Freeze command this.Delay(); // For induced delay #region Validate arguments (topic exists, locations exist...) if (topic == "") { throw new ApplicationException("Must select a topic!"); } if (clientName == "") { throw new ApplicationException("You do not have a username!"); } if (clientRA == null) { throw new ApplicationException("You did not provide a Remoting Address!"); } if (slots.Count == 0) { throw new ApplicationException("Must select slots on which you are available."); } // Check if a meeting with this topic exists if (Server.meetingPropList.Where(mp => mp.Topic == topic).Count() == 0) { throw new ApplicationException($"There is no meeting with topic '{topic}'."); } // Find repeated slots var myListSlots = new List <Slot>(); var duplicateSlots = new List <Slot>(); foreach (var s in slots) { if (!myListSlots.Contains(s)) { myListSlots.Add(s); } else { duplicateSlots.Add(s); } } if (duplicateSlots.Count > 0) { throw new ApplicationException("You have repeated slots."); } // Check if locations exist foreach (Slot s in slots) { if (!Server.locationRooms.ContainsKey(s.location)) { throw new ApplicationException($"Location '{s.location}' does not exist in the server."); } } #endregion foreach (MeetingProposal mp in Server.meetingPropList) { if (mp.Topic == topic) { //Causal and Total Order Check if object is not locked (Mutex) lock (mp.SyncLock) { if (mp.Status == MeetingProposal.StatusEnum.Closed) { throw new ApplicationException($"Meeting '{topic}' is closed."); } else if (mp.Status == MeetingProposal.StatusEnum.Cancelled) { throw new ApplicationException($"Meeting '{topic}' is cancelled."); } else if (mp.ClientsJoined.Keys.Contains(clientName)) { throw new ApplicationException($"You have already joined meeting '{topic}'."); } else if (mp.Invitees.Count > 0 && mp.CoordinatorUsername != clientName && !mp.Invitees.Contains(clientName)) { throw new ApplicationException($"You have not been invited for meeting '{topic}'!"); } foreach (Slot s in slots) { if (!mp.Slots.Contains(s)) { throw new ApplicationException($"Slot '{s.ToString()}' does not exist in this meeting."); } } mp.AddClientToMeeting(clientName, clientRA, slots); //Inform server replicas that new client joined meeting Thread threadS = new Thread(() => Server.InformAllServersOfJoinedMeeting(mp, clientName, clientRA, slots)); threadS.Start(); //Inform all clients Thread thread = new Thread(() => Server.InformAllClientsOfJoinedMeeting(mp, clientName)); thread.Start(); } } } }