Monitor
CommandManager.cs
Go to the documentation of this file.
1 //
2 // CommandManager.cs
3 //
4 // Author:
5 // Di MERCURIO Sébastien <dimercur@insa-toulouse.fr>
6 //
7 // Copyright (c) 2018 INSA - DGEI
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22 using System.Threading;
23 
24 namespace monitor
25 {
31  public class CommandManager
32  {
36  public delegate void CommandReceivedEvent(string msg, byte[] buffer);
37  public CommandReceivedEvent commandReceivedEvent = null;
38 
42  private System.Timers.Timer waitTimer = new System.Timers.Timer();
43  private ManualResetEvent waitEvent = new ManualResetEvent(false);
44 
48  private bool waitForAcknowledge = false;
49 
53  private string messageReceived = null;
54 
58  private bool isBusy = false;
59 
64  {
65  AnswerReceived,
66  Timeout,
67  Busy
68  };
69 
74  public CommandManager(CommandReceivedEvent callback)
75  {
77 
78  this.commandReceivedEvent += callback;
79  waitTimer.Elapsed += OnMessageTimeout;
80  }
81 
87  {
88  Client.Close();
89  }
90 
96  public bool Open(string hostname)
97  {
98  return this.Open(hostname, Client.defaultPort);
99  }
100 
107  public bool Open(string hostname, int port)
108  {
109  return Client.Open(hostname, port);
110  }
111 
115  public void Close()
116  {
117  Client.Close();
118  }
119 
125  private void OnMessageReception(string message, byte[] buffer)
126  {
127  waitTimer.Stop(); // Stop timeout stopwatch
128 
129  this.messageReceived = message;
130  isBusy = false;
131 
132  // if SendCommand wait for an acknowledge, release semaphore waitEvent
133  // so that SendCommand will be able to read received answer
134  // Received answer will not be sent to upper level
135  if (waitForAcknowledge)
136  {
137  waitForAcknowledge = false;
138  waitEvent.Set(); // Envoi de l'evenement
139  }
140  else
141  // if sendCommand doesn't wait for an acknowledge, message received
142  // is for upper level, so call callback
143  {
144 
145  waitForAcknowledge = false;
146 
147  this.commandReceivedEvent?.Invoke(message, buffer);
148  }
149  }
150 
156  private void OnMessageTimeout(object sender, System.Timers.ElapsedEventArgs e)
157  {
158  messageReceived = null;
159  // set buffer and message as null to indicate that no message was received
160  // and call to OnMessagereception is due to timeout
161  OnMessageReception(messageReceived, null);
162  }
163 
171  public CommandManagerStatus SendCommand(string cmd, out string answer, double timeout)
172  {
173  CommandManagerStatus status = CommandManagerStatus.AnswerReceived;
174  answer = null;
175 
176 
177  if (isBusy) status = CommandManagerStatus.Busy;
178  else
179  {
180  isBusy = true;
181 
182  // Send command to server
183  Client.Write(cmd);
184 
185  if (timeout > 0) // Command request an acknowledge
186  {
187 
188  waitForAcknowledge = true; // Flag used in OnMessageReception callback to avoid
189  // sending acknowledge message to upper level
190  waitTimer.Interval = timeout;
191  waitTimer.Start(); // Start timeout timer
192 
193  waitEvent.WaitOne(); // Stop current thread, waiting for waitEvent semaphore
194  // produced in OnMessageReception when either a message is received
195  // or a timeout occur
196 
197  waitEvent.Reset(); // reset semaphore for next message
198 
199  if (this.messageReceived == null) // timeout: server connection error
200  {
201  status = CommandManagerStatus.Timeout;
202  }
203  }
204  else isBusy = false;
205 
206  // return received answer, null in case of timeout
207  answer = this.messageReceived;
208  this.messageReceived = null;
209  }
210 
211  return status;
212  }
213  }
214 }
void OnMessageTimeout(object sender, System.Timers.ElapsedEventArgs e)
Callback called by stopwatch on timeout
const int defaultPort
Default server port number
Definition: Client.cs:41
bool Open(string hostname)
Open the specified hostname server, using default port number.
static void Write(string mes)
Write a string to server
Definition: Client.cs:219
Command Manager. Use for timeout managment during reception of data Used as intermediate layer betwee...
delegate void CommandReceivedEvent(string msg, byte[] buffer)
Callback for sending received data to upper level
CommandManagerStatus SendCommand(string cmd, out string answer, double timeout)
Sends a command to TCP server
bool isBusy
flag indicating command manager is currently busy waiting an acknowledge
void OnMessageReception(string message, byte[] buffer)
Callback called by Client class after reception of new message
CommandReceivedEvent commandReceivedEvent
System.Timers.Timer waitTimer
Timer for managing timeout
ManualResetEvent waitEvent
static bool Open(string host)
Open connection to server "host", on default port number.
Definition: Client.cs:89
Static class for TCP client
Definition: Client.cs:31
static void Close()
Close connection to server
Definition: Client.cs:141
CommandManagerStatus
Available status when sending command
static ReadEvent readEvent
Definition: Client.cs:82
bool Open(string hostname, int port)
Open connection to server "host", with port number "port"
string messageReceived
received message
CommandManager(CommandReceivedEvent callback)
Initializes a new instance of the T:monitor.CommandManager class.
~CommandManager()
Releases unmanaged resources and performs other cleanup operations before the T:monitor.CommandManager is reclaimed by garbage collection.
bool waitForAcknowledge
Flag to tell rogram to wait for an acknowledge from server
void Close()
Close connection to server