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: }