Reworking our protocols. Client name now displayed in our clients tab.
1.1 --- a/Client/Client.cs Fri Aug 15 11:11:17 2014 +0200
1.2 +++ b/Client/Client.cs Fri Aug 15 13:26:38 2014 +0200
1.3 @@ -33,7 +33,7 @@
1.4 }
1.5
1.6
1.7 - public void OnServerClosing()
1.8 + public void OnCloseOrder()
1.9 {
1.10 //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
1.11 //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
1.12 @@ -64,16 +64,10 @@
1.13 : base(callbackInstance, new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService"))
1.14 { }
1.15
1.16 - public void Connect(string aClientName)
1.17 + public void SetName(string aClientName)
1.18 {
1.19 Name = aClientName;
1.20 - Channel.Connect(aClientName);
1.21 - }
1.22 -
1.23 - public void Disconnect()
1.24 - {
1.25 - Channel.Disconnect(Name);
1.26 - Name = "";
1.27 + Channel.SetName(aClientName);
1.28 }
1.29
1.30 public void SetText(int aLineIndex, string aText)
1.31 @@ -81,13 +75,14 @@
1.32 Channel.SetText(aLineIndex, aText);
1.33 }
1.34
1.35 -
1.36 public void SetTexts(System.Collections.Generic.IList<string> aTexts)
1.37 {
1.38 Channel.SetTexts(aTexts);
1.39 }
1.40
1.41 -
1.42 -
1.43 + public int ClientCount()
1.44 + {
1.45 + return Channel.ClientCount();
1.46 + }
1.47 }
1.48 }
2.1 --- a/Client/MainForm.cs Fri Aug 15 11:11:17 2014 +0200
2.2 +++ b/Client/MainForm.cs Fri Aug 15 13:26:38 2014 +0200
2.3 @@ -39,10 +39,11 @@
2.4 iClient = new Client(instanceContext);
2.5
2.6 //Connect using unique name
2.7 - string name = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt");
2.8 - iClient.Connect(name);
2.9 + //string name = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt");
2.10 + string name = "Client-" + (iClient.ClientCount() - 1);
2.11 + iClient.SetName(name);
2.12 //Text = Text + ": " + name;
2.13 - Text = Text + ": " + iClient.SessionId;
2.14 + Text = "[[" + name + "]] " + iClient.SessionId;
2.15
2.16 }
2.17
2.18 @@ -67,7 +68,6 @@
2.19 //We are in the proper thread
2.20 if (IsClientReady())
2.21 {
2.22 - //iClient.Disconnect();
2.23 Trace.TraceInformation("Closing client: " + iClient.SessionId);
2.24 iClient.Close();
2.25 Trace.TraceInformation("Closed client: " + iClient.SessionId);
2.26 @@ -99,11 +99,6 @@
2.27
2.28 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
2.29 {
2.30 - if (IsClientReady()) //Could catch exception instead
2.31 - {
2.32 - iClient.Disconnect();
2.33 - }
2.34 -
2.35 CloseConnectionThreadSafe();
2.36 }
2.37
3.1 --- a/Interface/Interface.cs Fri Aug 15 11:11:17 2014 +0200
3.2 +++ b/Interface/Interface.cs Fri Aug 15 13:26:38 2014 +0200
3.3 @@ -14,17 +14,41 @@
3.4 SessionMode = SessionMode.Required)]
3.5 public interface IDisplayService
3.6 {
3.7 + /// <summary>
3.8 + /// Set the name of this client.
3.9 + /// Name is a convenient way to recognize your client.
3.10 + /// Naming you client is not mandatory.
3.11 + /// In the absence of a name the session ID is often used instead.
3.12 + /// </summary>
3.13 + /// <param name="aClientName"></param>
3.14 [OperationContract(IsOneWay = true)]
3.15 - void Connect(string aClientName);
3.16 + void SetName(string aClientName);
3.17
3.18 + /// <summary>
3.19 + /// Put the given text in the given field on your display.
3.20 + /// Fields are often just lines of text.
3.21 + /// </summary>
3.22 + /// <param name="aFieldIndex"></param>
3.23 + /// <param name="aText"></param>
3.24 [OperationContract(IsOneWay = true)]
3.25 - void Disconnect(string aClientName);
3.26 + void SetText(int aFieldIndex, string aText);
3.27
3.28 - [OperationContract(IsOneWay = true)]
3.29 - void SetText(int aLineIndex, string aText);
3.30 -
3.31 + /// <summary>
3.32 + /// Allows a client to set multiple text fields at once.
3.33 + /// First text in the list is set into field index 0.
3.34 + /// Last text in the list is set into field index N-1.
3.35 + /// </summary>
3.36 + /// <param name="aTexts"></param>
3.37 [OperationContract(IsOneWay = true)]
3.38 void SetTexts(System.Collections.Generic.IList<string> aTexts);
3.39 +
3.40 + /// <summary>
3.41 + /// Provides the number of clients currently connected
3.42 + /// </summary>
3.43 + /// <returns></returns>
3.44 + [OperationContract()]
3.45 + int ClientCount();
3.46 +
3.47 }
3.48
3.49
3.50 @@ -33,8 +57,12 @@
3.51 [OperationContract(IsOneWay = true)]
3.52 void OnConnected();
3.53
3.54 + /// <summary>
3.55 + /// Tell our client to close its connection.
3.56 + /// Notably sent when the server is shutting down.
3.57 + /// </summary>
3.58 [OperationContract(IsOneWay = true)]
3.59 - void OnServerClosing();
3.60 + void OnCloseOrder();
3.61 }
3.62
3.63
4.1 --- a/Server/MainForm.cs Fri Aug 15 11:11:17 2014 +0200
4.2 +++ b/Server/MainForm.cs Fri Aug 15 13:26:38 2014 +0200
4.3 @@ -357,6 +357,7 @@
4.4 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
4.5 {
4.6 StopServer();
4.7 + e.Cancel = iClosing;
4.8 }
4.9
4.10 public void StartServer()
4.11 @@ -373,16 +374,24 @@
4.12
4.13 public void StopServer()
4.14 {
4.15 - //Tell connected client first? Is that possible?
4.16 -
4.17 - if (iClients.Count>0)
4.18 + if (iClients.Count > 0 && !iClosing)
4.19 {
4.20 //Tell our clients
4.21 + iClosing = true;
4.22 BroadcastCloseEvent();
4.23 }
4.24 -
4.25 - //iServiceHost.Close();
4.26 -
4.27 + else if (iClosing)
4.28 + {
4.29 + if (MessageBox.Show("Force exit?", "Waiting for clients...", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
4.30 + {
4.31 + iClosing = false; //We make sure we force close if asked twice
4.32 + }
4.33 + }
4.34 + else
4.35 + {
4.36 + //We removed that as it often lags for some reason
4.37 + //iServiceHost.Close();
4.38 + }
4.39 }
4.40
4.41 public void BroadcastCloseEvent()
4.42 @@ -397,7 +406,7 @@
4.43 try
4.44 {
4.45 Trace.TraceInformation("BroadcastCloseEvent - " + client.Key);
4.46 - client.Value.OnServerClosing(/*eventData*/);
4.47 + client.Value.OnCloseOrder(/*eventData*/);
4.48 }
4.49 catch (Exception ex)
4.50 {
4.51 @@ -449,6 +458,7 @@
4.52 public delegate void RemoveClientDelegate(string aSessionId);
4.53 public delegate void SetTextDelegate(int aLineIndex, string aText);
4.54 public delegate void SetTextsDelegate(System.Collections.Generic.IList<string> aTexts);
4.55 + public delegate void SetClientNameDelegate(string aSessionId, string aName);
4.56
4.57
4.58 /// <summary>
4.59 @@ -494,7 +504,16 @@
4.60 {
4.61 Program.iMainForm.iClients.Remove(aSessionId);
4.62 Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
4.63 - }
4.64 + }
4.65 +
4.66 + if (iClosing && iClients.Count == 0)
4.67 + {
4.68 + //We were closing our form
4.69 + //All clients are now closed
4.70 + //Just resume our close operation
4.71 + iClosing = false;
4.72 + Close();
4.73 + }
4.74 }
4.75 }
4.76
4.77 @@ -554,7 +573,38 @@
4.78 }
4.79 }
4.80 }
4.81 + }
4.82
4.83 +
4.84 + /// <summary>
4.85 + ///
4.86 + /// </summary>
4.87 + /// <param name="aSessionId"></param>
4.88 + /// <param name="aName"></param>
4.89 + public void SetClientNameThreadSafe(string aSessionId, string aName)
4.90 + {
4.91 + if (this.InvokeRequired)
4.92 + {
4.93 + //Not in the proper thread, invoke ourselves
4.94 + SetClientNameDelegate d = new SetClientNameDelegate(SetClientNameThreadSafe);
4.95 + this.Invoke(d, new object[] { aSessionId, aName });
4.96 + }
4.97 + else
4.98 + {
4.99 + //We are in the proper thread
4.100 + //Remove this session from both client collection and UI tree view
4.101 + if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
4.102 + {
4.103 + //Change our session node text
4.104 + TreeNode node = Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0];
4.105 + node.Text = aName;
4.106 + //Add a child with SessionId
4.107 + node.Nodes.Add(new TreeNode(aSessionId));
4.108 +
4.109 + //Program.iMainForm.iClients.Remove(aSessionId);
4.110 + //Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
4.111 + }
4.112 + }
4.113 }
4.114
4.115 }
5.1 --- a/Server/Servers.cs Fri Aug 15 11:11:17 2014 +0200
5.2 +++ b/Server/Servers.cs Fri Aug 15 13:26:38 2014 +0200
5.3 @@ -20,6 +20,7 @@
5.4 class DisplayServer : IDisplayService, IDisposable
5.5 {
5.6 public string SessionId { get; set; }
5.7 + public string Name { get; set; }
5.8
5.9 DisplayServer()
5.10 {
5.11 @@ -51,8 +52,10 @@
5.12 }
5.13
5.14 //
5.15 - public void Connect(string aClientName)
5.16 + public void SetName(string aClientName)
5.17 {
5.18 + Name = aClientName;
5.19 + Program.iMainForm.SetClientNameThreadSafe(SessionId, Name);
5.20 //Disconnect(aClientName);
5.21
5.22 //Register our client and its callback interface
5.23 @@ -64,17 +67,9 @@
5.24 }
5.25
5.26 ///
5.27 - public void Disconnect(string aClientName)
5.28 + public int ClientCount()
5.29 {
5.30 - //remove the old client if any
5.31 - /*
5.32 - if (Program.iMainForm.iClients.Keys.Contains(aClientName))
5.33 - {
5.34 - Program.iMainForm.iClients.Remove(aClientName);
5.35 - Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aClientName,false)[0]);
5.36 - }
5.37 - */
5.38 -
5.39 + return Program.iMainForm.iClients.Count;
5.40 }
5.41
5.42