public void updateClientState() { try { Task <Message> task = null; try { task = Task <Message> .Factory.StartNew(() => server.Response("GetSharedClientsList", null)); } catch (Exception e) { if (connectToBackup(0, new List <string>())) { task = Task <Message> .Factory.StartNew(() => server.Response("GetSharedClientsList", null)); } return; } bool taskCompleted = task.Wait(timeout); if (taskCompleted) { Message mess = task.Result; if (mess.getSucess()) { List <string> urls = (List <string>)mess.getObj(); ClientServ c = null; int index = 0; try{ c = (ClientServ)Activator.GetObject(typeof(ClientServ), urls[index]); } catch (Exception e) { c = (ClientServ)Activator.GetObject(typeof(ClientServ), urls[index + 1]); } List <MeetingProposal> update = c.getMeetingProposals(); if (update == null || update.Count == 0) { Console.WriteLine("Client doesn't have anything to update"); } else { foreach (MeetingProposal m in update) { cs.getUser().addMyMP(m); } Console.WriteLine("Client updated"); } } } } catch (Exception e) { Console.WriteLine("Unable to connect to the server"); } }
static void Main(string[] args) { TcpChannel channel; Cliente cli; String script = ""; if (args.Length == 2) { script = args[1]; } string[] vs = args[0].Split( new[] { "'" }, StringSplitOptions.None); String username = vs[0]; String cURL = vs[1]; String sURL = vs[2]; String[] sURLBackup; List <String> localClients = new List <String>(); cli = new Cliente(username, cURL, sURL, script); Uri myUri = new Uri(cURL); channel = new TcpChannel(myUri.Port); ChannelServices.RegisterChannel(channel, false); cs = new ClientServ(cli); //RemotingServices.Marshal(cs, "cc", typeof(ClientServ)); RemotingServices.Marshal(cs, myUri.Segments[1], typeof(ClientServ)); server = (ISchedulingServer)Activator.GetObject(typeof(ISchedulingServer), sURL); List <String> arg = new List <String>(); arg.Add(cURL); Message mess = null; // = server.Response("Register", arg); //it should wait but it should be a task! try { Task <Message> task = Task <Message> .Factory.StartNew(() => server.Response("Register", arg)); task.Wait(); mess = task.Result; } catch (Exception e) { //Should we give here another server for the Client to connect? Console.WriteLine("The server you tried to connect unfortunately is not available"); Console.WriteLine("Please close window and try to connect to another server adress"); Console.ReadLine(); } sURLBackup = Array.ConvertAll((object[])mess.getObj(), Convert.ToString); cs.setBackupServerURL(sURLBackup); cs.setLocalClients(localClients); Console.WriteLine("Cliente " + new Uri(cURL).Port + " (" + username + ") " + mess.getMessage()); //check if the client has to be updated cs.updateClientState(); if (args.Length == 1 || args.Length == 2) { Boolean run = true; Console.WriteLine("Hello, " + username + ". Welcome to MSDAD"); Console.WriteLine("Type list to list the user's meeting proposals"); Console.WriteLine("Type create <topic> <# of min participants> <# of slots> <# of invitees> [slots] [invitees] to create a new meeting proposal"); Console.WriteLine("Type join <meetingTopic> <# of slots> [slots] to join the specific meeting"); Console.WriteLine("Type close <meetingTopic> to close the specific meeting proposal"); Console.WriteLine("Type wait <time in milliseconds> to let the Cliente wait"); Console.WriteLine("Type quit to exit"); //if script client if (args.Length == 2) { string allScript = System.IO.File.ReadAllText(script); string[] commandList = allScript.Split( new[] { Environment.NewLine }, StringSplitOptions.None); Console.WriteLine("If you wish the script to be run stpe-by-step write YES"); String s = Console.ReadLine(); if (s.ToLower().Equals("yes")) { foreach (string command in commandList) { Console.WriteLine("Press Enter to execute the line:"); Console.WriteLine(command); Console.ReadLine(); cli.ProcessConsoleLine(command); } } else { foreach (string command in commandList) { cli.ProcessConsoleLine(command); } } } else { while (run) { Console.Write("Insert command: "); string command = Console.ReadLine(); if (command.Split( new[] { " " }, StringSplitOptions.None)[0].Equals("quit")) { System.Environment.Exit(1); } else { cli.ProcessConsoleLine(command); } } } } else { System.Console.WriteLine("ERROR: Wrong number of arguments!"); } }
//TODO we have to make all calls to the server fail proof, both from freezes and crashes public Boolean connectToBackup(int index, List <String> args) { Boolean _return = true; Console.WriteLine("Connection to Server lost. Trying to reconnect..."); try { args.Add(sURL); this.sURL = sURLBackup[index]; server = (ISchedulingServer)Activator.GetObject(typeof(ISchedulingServer), sURLBackup[index]); //server.Response("RemoveServerFromView", args).getMessage(); Task <Message> task = Task <Message> .Factory.StartNew(() => server.Response("RemoveServerFromView", args)); task.Wait(); List <String> arg = new List <String>(); arg.Add(cURL); Message mess; // = server.Response("Register", arg); task = Task <Message> .Factory.StartNew(() => server.Response("Register", arg)); // should we send an error here ? task.Wait(); mess = task.Result; sURLBackup = Array.ConvertAll((object[])mess.getObj(), Convert.ToString); Console.WriteLine("Cliente " + new Uri(cURL).Port + " (" + username + ") " + mess.getMessage()); //coordinate local clients to reconnect to different backup servers int pointer = index + 1 % sURLBackup.Length; foreach (string url in localClients) { if (url != cURL) { ClientServ c = (ClientServ)Activator.GetObject(typeof(ClientServ), url); c.connectToBackup(pointer % sURLBackup.Length, new List <String>()); pointer++; } } _return = true; } catch (Exception e) { Console.WriteLine(e); try { if (index + 1 < sURLBackup.Length) { connectToBackup(index + 1, args); } else { Console.WriteLine("Error: No Backup-server reachable!"); _return = false; } } catch (Exception e2) { _return = false; } } return(_return); }
// this can be to share the proposal we created or the redirect a received proposal public void ShareProposal(MeetingProposal mp, List <string> urls, string serv) { //update the list of clients from the server when the call didn't came from a client on //the same server if (!serv.Equals(this.sURL)) { try { Task <Message> task = null; try { task = Task <Message> .Factory.StartNew(() => server.Response("GetSharedClientsList", null)); } catch (Exception e) { if (connectToBackup(0, new List <string>())) { task = Task <Message> .Factory.StartNew(() => server.Response("GetSharedClientsList", null)); } return; } bool taskCompleted = task.Wait(timeout); if (taskCompleted) { Message output = task.Result; //get the list for the new gossip group urls = (List <string>)output.getObj(); //update the server identifier serv = this.sURL; //remove the client url from that list urls.Remove(cURL); } } catch (Exception e) { Console.WriteLine("Connection to server failed"); } } if (serv.Equals(this.sURL) && urls.Count == 0) { //terminal condition } else if (urls.Count < gossipParam) { //when we have less than gossipParam clients to share foreach (string u in urls) { ClientServ c = (ClientServ)Activator.GetObject(typeof(ClientServ), u); c.receiveProposal(mp, new List <string>(), serv); } } else { //when we have more than gossipParam clients to share List <string> myURLs = new List <string>(); List <string> removeList = new List <string>(); for (int w = 0; w < gossipParam; w++) { removeList.Add(urls[w]); } foreach (string rmv in removeList) { myURLs.Add(rmv); urls.Remove(rmv); } //divide the list and create a new one for each client //given by the gossipParam int standardSize = urls.Count / gossipParam; int rest = urls.Count % gossipParam; List <string>[] otherURLs = new List <string> [gossipParam]; for (int init = 0; init < otherURLs.Length; init++) { otherURLs[init] = new List <string>(); } int counter = 0; //first distribute the client urls giving standardSize urls //to each one for (int i = 0; i < otherURLs.Length; i++) { for (int j = 0; j < standardSize; j++) { otherURLs[i].Add(urls[j + counter]); } counter += standardSize; } //if there is any urls left to distribute, do it, by giving one //to each list for (int i = 0; i < otherURLs.Length && rest > 0; i++) { otherURLs[i].Add(urls[i + counter]); rest--; } //propagate the meeting proposals for (int i = 0; i < myURLs.Count; i++) { //prevent sending to itself if (myURLs[i] != cURL) { ClientServ c = (ClientServ)Activator.GetObject(typeof(ClientServ), myURLs[i]); if (c != null) { c.receiveProposal(mp, otherURLs[i], serv); } } } } }