Prevent stackoverflow when client reconnects.
Client now specifies layout rather than relying on default one.
2 using System.Collections.Generic;
5 using System.Threading.Tasks;
6 using System.Windows.Forms;
8 using System.ServiceModel;
9 using System.ServiceModel.Channels;
12 namespace SharpDisplayClient
17 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
18 public class Callback : ICallback, IDisposable
20 private MainForm MainForm { get; set; }
22 public Callback(MainForm aMainForm)
27 public void OnConnected()
29 //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
30 //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
32 MessageBox.Show("OnConnected()", "Client");
36 public void OnCloseOrder()
38 //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
39 //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
41 //MessageBox.Show("OnServerClosing()", "Client");
42 MainForm.CloseConnectionThreadSafe();
43 MainForm.CloseThreadSafe();
57 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
58 public class Client : DuplexClientBase<IService>
60 public string SessionId { get { return InnerChannel.SessionId; } }
62 public Client(ICallback aCallback)
63 : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService"))
66 public void SetName(string aClientName)
68 Channel.SetName(aClientName);
71 public void SetLayout(TableLayout aLayout)
73 Channel.SetLayout(aLayout);
76 public void SetField(DataField aField)
78 Channel.SetField(aField);
81 public void SetFields(System.Collections.Generic.IList<DataField> aFields)
83 Channel.SetFields(aFields);
86 public int ClientCount()
88 return Channel.ClientCount();
93 return State == CommunicationState.Opened || State == CommunicationState.Created;
99 /// Handle connection with our Sharp Display Server.
100 /// If the connection is faulted it will attempt to restart it.
102 public class DisplayClient
104 private Client iClient;
105 private Callback iCallback;
106 private bool resetingConnection = false;
108 private MainForm MainForm { get; set; }
109 public string SessionId { get { return iClient.SessionId; } }
110 public string Name { get; private set; }
111 private TableLayout Layout { get; set; }
112 private System.Collections.Generic.IList<DataField> Fields { get; set; }
115 public DisplayClient(MainForm aMainForm)
117 MainForm = aMainForm;
119 Fields = new DataField[]{};
123 /// Initialize our server connection.
127 iCallback = new Callback(MainForm);
128 iClient = new Client(iCallback);
132 /// Terminate our server connection.
143 /// Tells whether a server connection is available.
145 /// <returns>True if a server connection is available. False otherwise.</returns>
146 public bool IsReady()
148 return (iClient != null && iCallback != null && iClient.IsReady());
152 /// Check if our server connection is available and attempt reset it if it isn't.
153 /// This is notably dealing with timed out connections.
155 public void CheckConnection()
157 if (!IsReady() && !resetingConnection)
162 //Avoid stack overflow in case of persisting failure
163 resetingConnection = true;
167 //On reconnect there is a bunch of properties we need to reset
170 iClient.SetName(Name);
178 //Make sure our this state does not get out of sync
179 resetingConnection = true;
184 public void SetName(string aClientName)
188 iClient.SetName(aClientName);
192 public void SetLayout(TableLayout aLayout)
196 iClient.SetLayout(aLayout);
200 public void SetField(DataField aField)
202 //TODO: Create fields if not present
204 foreach (DataField field in Fields)
206 if (field.Index == aField.Index)
208 //Update our field then
216 iClient.SetField(aField);
219 public void SetFields(System.Collections.Generic.IList<DataField> aFields)
223 iClient.SetFields(aFields);
227 public int ClientCount()
230 return iClient.ClientCount();