StephaneLenclud@447:  StephaneLenclud@445: using System; StephaneLenclud@445: using System.Collections.Generic; StephaneLenclud@447: using System.Linq; StephaneLenclud@445: using System.Text; StephaneLenclud@447: using System.Threading.Tasks; StephaneLenclud@445: using System.Windows.Forms; StephaneLenclud@447: using SharpDisplay; StephaneLenclud@445: using System.ServiceModel; StephaneLenclud@447: using System.ServiceModel.Channels; StephaneLenclud@447: StephaneLenclud@445: StephaneLenclud@445: namespace SharpDisplay StephaneLenclud@445: { StephaneLenclud@446: /// StephaneLenclud@446: /// StephaneLenclud@446: /// StephaneLenclud@447: [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] StephaneLenclud@447: public class Callback : ICallback, IDisposable StephaneLenclud@446: { StephaneLenclud@447: private DisplayClient DisplayClient { get; set; } StephaneLenclud@446: StephaneLenclud@447: public Callback(DisplayClient aClient) StephaneLenclud@447: { StephaneLenclud@447: DisplayClient = aClient; StephaneLenclud@447: } StephaneLenclud@446: StephaneLenclud@447: public void OnConnected() StephaneLenclud@447: { StephaneLenclud@447: //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread); StephaneLenclud@447: //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId); StephaneLenclud@446: StephaneLenclud@447: MessageBox.Show("OnConnected()", "Client"); StephaneLenclud@447: } StephaneLenclud@446: StephaneLenclud@447: StephaneLenclud@447: public void OnCloseOrder() StephaneLenclud@447: { StephaneLenclud@447: DisplayClient.Close(); StephaneLenclud@447: //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread); StephaneLenclud@447: //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId); StephaneLenclud@447: StephaneLenclud@447: //MessageBox.Show("OnServerClosing()", "Client"); StephaneLenclud@447: //MainForm.CloseConnectionThreadSafe(); StephaneLenclud@447: //MainForm.CloseThreadSafe(); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: //From IDisposable StephaneLenclud@447: public void Dispose() StephaneLenclud@447: { StephaneLenclud@447: StephaneLenclud@447: } StephaneLenclud@446: } StephaneLenclud@446: StephaneLenclud@446: StephaneLenclud@446: /// StephaneLenclud@445: /// StephaneLenclud@445: /// StephaneLenclud@445: [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] StephaneLenclud@445: public class Client : DuplexClientBase StephaneLenclud@445: { StephaneLenclud@445: public string SessionId { get { return InnerChannel.SessionId; } } StephaneLenclud@445: StephaneLenclud@445: public Client(ICallback aCallback) StephaneLenclud@445: : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService")) StephaneLenclud@445: { } StephaneLenclud@445: StephaneLenclud@445: public void SetName(string aClientName) StephaneLenclud@445: { StephaneLenclud@445: Channel.SetName(aClientName); StephaneLenclud@445: } StephaneLenclud@445: StephaneLenclud@446: public void SetLayout(TableLayout aLayout) StephaneLenclud@446: { StephaneLenclud@446: Channel.SetLayout(aLayout); StephaneLenclud@446: } StephaneLenclud@446: StephaneLenclud@447: public void SetField(DataField aField) StephaneLenclud@445: { StephaneLenclud@447: Channel.SetField(aField); StephaneLenclud@445: } StephaneLenclud@445: StephaneLenclud@447: public void SetFields(System.Collections.Generic.IList aFields) StephaneLenclud@445: { StephaneLenclud@447: Channel.SetFields(aFields); StephaneLenclud@445: } StephaneLenclud@445: StephaneLenclud@445: public int ClientCount() StephaneLenclud@445: { StephaneLenclud@445: return Channel.ClientCount(); StephaneLenclud@445: } StephaneLenclud@445: StephaneLenclud@445: public bool IsReady() StephaneLenclud@445: { StephaneLenclud@447: return State == CommunicationState.Opened || State == CommunicationState.Created; StephaneLenclud@445: } StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Handle connection with our Sharp Display Server. StephaneLenclud@447: /// If the connection is faulted it will attempt to restart it. StephaneLenclud@447: /// StephaneLenclud@447: public class DisplayClient StephaneLenclud@447: { StephaneLenclud@447: private Client iClient; StephaneLenclud@447: private Callback iCallback; StephaneLenclud@447: private bool resetingConnection = false; StephaneLenclud@447: StephaneLenclud@447: //private MainForm MainForm { get; set; } StephaneLenclud@447: public string SessionId { get { return iClient.SessionId; } } StephaneLenclud@447: public string Name { get; private set; } StephaneLenclud@447: private TableLayout Layout { get; set; } StephaneLenclud@447: private System.Collections.Generic.IList Fields { get; set; } StephaneLenclud@447: StephaneLenclud@447: StephaneLenclud@447: public DisplayClient(/*MainForm aMainForm*/) StephaneLenclud@447: { StephaneLenclud@447: //MainForm = aMainForm; StephaneLenclud@447: Name = ""; StephaneLenclud@447: Fields = new DataField[]{}; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Initialize our server connection. StephaneLenclud@447: /// StephaneLenclud@447: public void Open() StephaneLenclud@447: { StephaneLenclud@447: iCallback = new Callback(this); StephaneLenclud@447: iClient = new Client(iCallback); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Terminate our server connection. StephaneLenclud@447: /// StephaneLenclud@447: public void Close() StephaneLenclud@447: { StephaneLenclud@447: iClient.Close(); StephaneLenclud@447: iClient = null; StephaneLenclud@447: iCallback.Dispose(); StephaneLenclud@447: iCallback = null; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Tells whether a server connection is available. StephaneLenclud@447: /// StephaneLenclud@447: /// True if a server connection is available. False otherwise. StephaneLenclud@447: public bool IsReady() StephaneLenclud@447: { StephaneLenclud@447: return (iClient != null && iCallback != null && iClient.IsReady()); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Check if our server connection is available and attempt reset it if it isn't. StephaneLenclud@447: /// This is notably dealing with timed out connections. StephaneLenclud@447: /// StephaneLenclud@447: public void CheckConnection() StephaneLenclud@447: { StephaneLenclud@447: if (!IsReady() && !resetingConnection) StephaneLenclud@447: { StephaneLenclud@447: //Try to reconnect StephaneLenclud@447: Open(); StephaneLenclud@447: StephaneLenclud@447: //Avoid stack overflow in case of persisting failure StephaneLenclud@447: resetingConnection = true; StephaneLenclud@447: StephaneLenclud@447: try StephaneLenclud@447: { StephaneLenclud@447: //On reconnect there is a bunch of properties we need to reset StephaneLenclud@447: if (Name != "") StephaneLenclud@447: { StephaneLenclud@447: iClient.SetName(Name); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: SetLayout(Layout); StephaneLenclud@447: iClient.SetFields(Fields); StephaneLenclud@447: } StephaneLenclud@447: finally StephaneLenclud@447: { StephaneLenclud@447: //Make sure our this state does not get out of sync StephaneLenclud@447: resetingConnection = true; StephaneLenclud@447: } StephaneLenclud@447: } StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: public void SetName(string aClientName) StephaneLenclud@447: { StephaneLenclud@447: Name = aClientName; StephaneLenclud@447: CheckConnection(); StephaneLenclud@447: iClient.SetName(aClientName); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: StephaneLenclud@447: public void SetLayout(TableLayout aLayout) StephaneLenclud@447: { StephaneLenclud@447: Layout = aLayout; StephaneLenclud@447: CheckConnection(); StephaneLenclud@447: iClient.SetLayout(aLayout); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Set the specified field. StephaneLenclud@447: /// StephaneLenclud@447: /// StephaneLenclud@447: /// True if the specified field was set client side. False means you need to redefine all your fields using CreateFields. StephaneLenclud@447: public bool SetField(DataField aField) StephaneLenclud@447: { StephaneLenclud@447: int i = 0; StephaneLenclud@447: bool fieldFound = false; StephaneLenclud@447: foreach (DataField field in Fields) StephaneLenclud@447: { StephaneLenclud@447: if (field.Index == aField.Index) StephaneLenclud@447: { StephaneLenclud@447: //Update our field then StephaneLenclud@447: Fields[i] = aField; StephaneLenclud@447: fieldFound = true; StephaneLenclud@447: break; StephaneLenclud@447: } StephaneLenclud@447: i++; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: if (!fieldFound) StephaneLenclud@447: { StephaneLenclud@447: //Field not found, make to use SetFields with all your fields at least once after setting your layout. StephaneLenclud@447: return false; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: CheckConnection(); StephaneLenclud@447: iClient.SetField(aField); StephaneLenclud@447: return true; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Use this function when updating existing fields. StephaneLenclud@447: /// StephaneLenclud@447: /// StephaneLenclud@447: public bool SetFields(System.Collections.Generic.IList aFields) StephaneLenclud@447: { StephaneLenclud@447: int fieldFoundCount = 0; StephaneLenclud@447: foreach (DataField fieldUpdate in aFields) StephaneLenclud@447: { StephaneLenclud@447: int i = 0; StephaneLenclud@447: foreach (DataField existingField in Fields) StephaneLenclud@447: { StephaneLenclud@447: if (existingField.Index == fieldUpdate.Index) StephaneLenclud@447: { StephaneLenclud@447: //Update our field then StephaneLenclud@447: Fields[i] = fieldUpdate; StephaneLenclud@447: fieldFoundCount++; StephaneLenclud@447: //Move on to the next field StephaneLenclud@447: break; StephaneLenclud@447: } StephaneLenclud@447: i++; StephaneLenclud@447: } StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: // StephaneLenclud@447: if (fieldFoundCount!=aFields.Count) StephaneLenclud@447: { StephaneLenclud@447: //Field not found, make sure to use SetFields with all your fields at least once after setting your layout. StephaneLenclud@447: return false; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: CheckConnection(); StephaneLenclud@447: iClient.SetFields(aFields); StephaneLenclud@447: return true; StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: /// StephaneLenclud@447: /// Use this function when creating your fields. StephaneLenclud@447: /// StephaneLenclud@447: /// StephaneLenclud@447: public void CreateFields(System.Collections.Generic.IList aFields) StephaneLenclud@447: { StephaneLenclud@447: Fields = aFields; StephaneLenclud@447: CheckConnection(); StephaneLenclud@447: iClient.SetFields(aFields); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: public int ClientCount() StephaneLenclud@447: { StephaneLenclud@447: CheckConnection(); StephaneLenclud@447: return iClient.ClientCount(); StephaneLenclud@447: } StephaneLenclud@447: StephaneLenclud@447: StephaneLenclud@445: StephaneLenclud@445: } StephaneLenclud@445: StephaneLenclud@445: StephaneLenclud@447: }