1.1 --- a/Client/Client.cs Tue Sep 29 18:38:36 2015 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,325 +0,0 @@
1.4 -//
1.5 -// Copyright (C) 2014-2015 Stéphane Lenclud.
1.6 -//
1.7 -// This file is part of SharpDisplayManager.
1.8 -//
1.9 -// SharpDisplayManager is free software: you can redistribute it and/or modify
1.10 -// it under the terms of the GNU General Public License as published by
1.11 -// the Free Software Foundation, either version 3 of the License, or
1.12 -// (at your option) any later version.
1.13 -//
1.14 -// SharpDisplayManager is distributed in the hope that it will be useful,
1.15 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 -// GNU General Public License for more details.
1.18 -//
1.19 -// You should have received a copy of the GNU General Public License
1.20 -// along with SharpDisplayManager. If not, see <http://www.gnu.org/licenses/>.
1.21 -//
1.22 -
1.23 -using System;
1.24 -using System.Collections.Generic;
1.25 -using System.Linq;
1.26 -using System.Text;
1.27 -using System.Threading.Tasks;
1.28 -using System.Windows.Forms;
1.29 -using SharpDisplay;
1.30 -using System.ServiceModel;
1.31 -using System.ServiceModel.Channels;
1.32 -
1.33 -
1.34 -namespace SharpDisplayClient
1.35 -{
1.36 - /// <summary>
1.37 - /// Client side Sharp Display callback implementation.
1.38 - /// </summary>
1.39 - [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
1.40 - public class Callback : ICallback, IDisposable
1.41 - {
1.42 - private MainForm MainForm { get; set; }
1.43 -
1.44 - public Callback(MainForm aMainForm)
1.45 - {
1.46 - MainForm = aMainForm;
1.47 - }
1.48 -
1.49 - /// <summary>
1.50 - /// Not used I believe.
1.51 - /// </summary>
1.52 - public void OnConnected()
1.53 - {
1.54 - //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
1.55 - //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
1.56 -
1.57 - MessageBox.Show("OnConnected()", "Client");
1.58 - }
1.59 -
1.60 -
1.61 - public void OnCloseOrder()
1.62 - {
1.63 - //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
1.64 - //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
1.65 -
1.66 - //MessageBox.Show("OnServerClosing()", "Client");
1.67 - MainForm.CloseConnectionThreadSafe();
1.68 - MainForm.CloseThreadSafe();
1.69 - }
1.70 -
1.71 - //From IDisposable
1.72 - public void Dispose()
1.73 - {
1.74 -
1.75 - }
1.76 - }
1.77 -
1.78 -
1.79 - /// <summary>
1.80 - /// Client side implementation of our Sharp Display Service.
1.81 - /// </summary>
1.82 - [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
1.83 - public class Client : DuplexClientBase<IService>
1.84 - {
1.85 - public string SessionId { get { return InnerChannel.SessionId; } }
1.86 -
1.87 - public Client(ICallback aCallback)
1.88 - : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService"))
1.89 - { }
1.90 -
1.91 - public void SetName(string aClientName)
1.92 - {
1.93 - Channel.SetName(aClientName);
1.94 - }
1.95 -
1.96 - public void SetLayout(TableLayout aLayout)
1.97 - {
1.98 - Channel.SetLayout(aLayout);
1.99 - }
1.100 -
1.101 - public void SetField(DataField aField)
1.102 - {
1.103 - Channel.SetField(aField);
1.104 - }
1.105 -
1.106 - public void SetFields(System.Collections.Generic.IList<DataField> aFields)
1.107 - {
1.108 - Channel.SetFields(aFields);
1.109 - }
1.110 -
1.111 - public int ClientCount()
1.112 - {
1.113 - return Channel.ClientCount();
1.114 - }
1.115 -
1.116 - public bool IsReady()
1.117 - {
1.118 - return State == CommunicationState.Opened || State == CommunicationState.Created;
1.119 - }
1.120 - }
1.121 -
1.122 -
1.123 - /// <summary>
1.124 - /// Handle connection with our Sharp Display Server.
1.125 - /// If the connection is faulted it will attempt to restart it.
1.126 - /// </summary>
1.127 - public class DisplayClient
1.128 - {
1.129 - private Client iClient;
1.130 - private Callback iCallback;
1.131 - private bool resetingConnection = false;
1.132 -
1.133 - private MainForm MainForm { get; set; }
1.134 - public string SessionId { get { return iClient.SessionId; } }
1.135 - public string Name { get; private set; }
1.136 - private TableLayout Layout { get; set; }
1.137 - private System.Collections.Generic.IList<DataField> Fields { get; set; }
1.138 -
1.139 -
1.140 - public DisplayClient(MainForm aMainForm)
1.141 - {
1.142 - MainForm = aMainForm;
1.143 - Name = "";
1.144 - Fields = new DataField[]{};
1.145 - }
1.146 -
1.147 - /// <summary>
1.148 - /// Initialize our server connection.
1.149 - /// </summary>
1.150 - public void Open()
1.151 - {
1.152 - iCallback = new Callback(MainForm);
1.153 - iClient = new Client(iCallback);
1.154 - }
1.155 -
1.156 - /// <summary>
1.157 - /// Terminate our server connection.
1.158 - /// </summary>
1.159 - public void Close()
1.160 - {
1.161 - iClient.Close();
1.162 - iClient = null;
1.163 - iCallback.Dispose();
1.164 - iCallback = null;
1.165 - }
1.166 -
1.167 - /// <summary>
1.168 - /// Tells whether a server connection is available.
1.169 - /// </summary>
1.170 - /// <returns>True if a server connection is available. False otherwise.</returns>
1.171 - public bool IsReady()
1.172 - {
1.173 - return (iClient != null && iCallback != null && iClient.IsReady());
1.174 - }
1.175 -
1.176 - /// <summary>
1.177 - /// Check if our server connection is available and attempt reset it if it isn't.
1.178 - /// This is notably dealing with timed out connections.
1.179 - /// </summary>
1.180 - public void CheckConnection()
1.181 - {
1.182 - if (!IsReady() && !resetingConnection)
1.183 - {
1.184 - //Try to reconnect
1.185 - Open();
1.186 -
1.187 - //Avoid stack overflow in case of persisting failure
1.188 - resetingConnection = true;
1.189 -
1.190 - try
1.191 - {
1.192 - //On reconnect there is a bunch of properties we need to reset
1.193 - if (Name != "")
1.194 - {
1.195 - iClient.SetName(Name);
1.196 - }
1.197 -
1.198 - SetLayout(Layout);
1.199 - iClient.SetFields(Fields);
1.200 - }
1.201 - finally
1.202 - {
1.203 - //Make sure our this state does not get out of sync
1.204 - resetingConnection = true;
1.205 - }
1.206 - }
1.207 - }
1.208 -
1.209 - /// <summary>
1.210 - /// Set our client's name.
1.211 - /// Client's name is typically user friendly.
1.212 - /// It does not have to be unique.
1.213 - /// </summary>
1.214 - /// <param name="aClientName">Our client name.</param>
1.215 - public void SetName(string aClientName)
1.216 - {
1.217 - Name = aClientName;
1.218 - CheckConnection();
1.219 - iClient.SetName(aClientName);
1.220 - }
1.221 -
1.222 - /// <summary>
1.223 - /// Set your client fields' layout.
1.224 - /// </summary>
1.225 - /// <param name="aLayout">The layout to apply for this client.</param>
1.226 - public void SetLayout(TableLayout aLayout)
1.227 - {
1.228 - Layout = aLayout;
1.229 - CheckConnection();
1.230 - iClient.SetLayout(aLayout);
1.231 - }
1.232 -
1.233 - /// <summary>
1.234 - /// Set the specified field.
1.235 - /// </summary>
1.236 - /// <param name="aField"></param>
1.237 - /// <returns>True if the specified field was set client side. False means you need to redefine all your fields using CreateFields.</returns>
1.238 - public bool SetField(DataField aField)
1.239 - {
1.240 - int i = 0;
1.241 - bool fieldFound = false;
1.242 - foreach (DataField field in Fields)
1.243 - {
1.244 - if (field.Index == aField.Index)
1.245 - {
1.246 - //Update our field then
1.247 - Fields[i] = aField;
1.248 - fieldFound = true;
1.249 - break;
1.250 - }
1.251 - i++;
1.252 - }
1.253 -
1.254 - if (!fieldFound)
1.255 - {
1.256 - //Field not found, make sure to use CreateFields first after setting your layout.
1.257 - return false;
1.258 - }
1.259 -
1.260 - CheckConnection();
1.261 - iClient.SetField(aField);
1.262 - return true;
1.263 - }
1.264 -
1.265 - /// <summary>
1.266 - /// Use this function when updating existing fields.
1.267 - /// </summary>
1.268 - /// <param name="aFields"></param>
1.269 - public bool SetFields(System.Collections.Generic.IList<DataField> aFields)
1.270 - {
1.271 - int fieldFoundCount = 0;
1.272 - foreach (DataField fieldUpdate in aFields)
1.273 - {
1.274 - int i = 0;
1.275 - foreach (DataField existingField in Fields)
1.276 - {
1.277 - if (existingField.Index == fieldUpdate.Index)
1.278 - {
1.279 - //Update our field then
1.280 - Fields[i] = fieldUpdate;
1.281 - fieldFoundCount++;
1.282 - //Move on to the next field
1.283 - break;
1.284 - }
1.285 - i++;
1.286 - }
1.287 - }
1.288 -
1.289 - //
1.290 - if (fieldFoundCount!=aFields.Count)
1.291 - {
1.292 - //Field not found, make sure to use CreateFields first after setting your layout.
1.293 - return false;
1.294 - }
1.295 -
1.296 - CheckConnection();
1.297 - iClient.SetFields(aFields);
1.298 - return true;
1.299 - }
1.300 -
1.301 - /// <summary>
1.302 - /// Use this function when creating your fields.
1.303 - /// This must be done at least once after setting your layout.
1.304 - /// </summary>
1.305 - /// <param name="aFields"></param>
1.306 - public void CreateFields(System.Collections.Generic.IList<DataField> aFields)
1.307 - {
1.308 - Fields = aFields;
1.309 - CheckConnection();
1.310 - iClient.SetFields(aFields);
1.311 - }
1.312 -
1.313 - /// <summary>
1.314 - /// Provide the number of clients currently connected to our server.
1.315 - /// </summary>
1.316 - /// <returns>Number of clients currently connected to our server.</returns>
1.317 - public int ClientCount()
1.318 - {
1.319 - CheckConnection();
1.320 - return iClient.ClientCount();
1.321 - }
1.322 -
1.323 -
1.324 -
1.325 - }
1.326 -
1.327 -
1.328 -}