From 92757a8d629812303ff3665343bd098917cca611 Mon Sep 17 00:00:00 2001 From: fcolin Date: Thu, 1 Feb 2007 12:04:16 +0000 Subject: modification structure svn --- IvyToDel/Ivy/IvyClient.cs | 592 ---------------------------------------------- 1 file changed, 592 deletions(-) delete mode 100644 IvyToDel/Ivy/IvyClient.cs (limited to 'IvyToDel/Ivy/IvyClient.cs') diff --git a/IvyToDel/Ivy/IvyClient.cs b/IvyToDel/Ivy/IvyClient.cs deleted file mode 100644 index 3db9f0f..0000000 --- a/IvyToDel/Ivy/IvyClient.cs +++ /dev/null @@ -1,592 +0,0 @@ -/// François-Régis Colin -/// http://www.tls.cena.fr/products/ivy/ -/// * -/// (C) CENA -/// * -namespace IvyBus -{ - using System; - using System.Collections; - using System.Collections.Specialized; - using System.Collections.Generic; - using System.Threading; - using System.Text; - using System.IO; - using System.Net; - using System.Net.Sockets; - using System.Configuration; - using System.Diagnostics; - - /// A Class for the the peers on the bus. - /// - /// - /// each time a connexion is made with a remote peer, the regexp are exchanged - /// once ready, a ready message is sent, and then we can send messages, - /// die messages, direct messages, add or remove regexps, or quit. A thread is - /// created for each remote client. - /// - public class IvyClient : IvyProtocol, IComparable, IDisposable - { - public int CompareTo(IvyClient other) - { - return (other.clientPriority - clientPriority); - } - - public String ApplicationName - { - get - { - return appName; - } - - } - - public List Regexps - { - get - { - List tab = new List(); - lock (bindings) - { - foreach (IvyBindingBase bind in bindings.Values) - tab.Add(bind.Expression); - } - return tab; - } - - } - internal int AppPort - { - get - { - return appPort; - } - - } - public IPAddress RemoteAddress - { - get - { - return remoteHost; - } - - } - public int RemotePort - { - get - { - return remotePort; - } - - } - - private Ivy bus; - private Dictionary bindings; - private int appPort; - private string clientId; /* an unique ID for each IvyClient */ - private int clientPriority; /* client priority */ - - private volatile Thread clientThread; // volatile to ensure the quick communication - private bool doping; // false by runtime default - private const int PINGTIMEOUT = 5000; - private volatile Thread pingerThread; - - private int remotePort; - private IPAddress remoteHost; - - // protected variables - internal String appName; - internal IvyProtocol stream; - - internal IvyClient(Ivy bus, Socket socket, string appname) - { - bindings = new Dictionary(); - appName = appname; - this.bus = bus; - - IPEndPoint endpoint = (IPEndPoint)socket.RemoteEndPoint; - - remoteHost = endpoint.Address; - remotePort = endpoint.Port; - -#if (!PocketPC ) - socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, 1 ); -#endif - - if ( bus.ProtocolVersion == 4 ) - stream = new IvyTCPStreamV4( socket, this ); - else - stream = new IvyTCPStreamV3(socket, this); - - clientPriority = Ivy.DEFAULT_PRIORITY; - // spawns a thread to manage the incoming traffic on this - // socket. We should be ready to receive messages now. - clientThread = new Thread(new ThreadStart(this.Run)); - clientThread.Name = "Ivy Tcp Client Reader Thread ("+appname+")"; - clientThread.Start(); - - } - - internal void SendBindings() - { - try - { - stream.TokenApplicationId(bus.applicationPriority, bus.AppId); - - // sends our ID, whether we initiated the connexion or not - // the ID is the couple "host name,application Port", the host name - // information is in the socket itself, the port is not known if we - // initiate the connexion - stream.TokenStartRegexp(bus.applicationPort, bus.appName); - // sends our regexps to the peer - lock (bus.bindings) - { - foreach (IvyApplicationBinding bind in bus.bindings.Values) - { - stream.TokenAddBinding(bind.Binding, bind.Key, bind.FormatedExpression); - } - } - stream.TokenEndRegexp(); - -#if (!PocketPC) - doping = Properties.Settings.Default.IvyPing; -#endif - if (doping) - { - pingerThread = new Thread(new ThreadStart(PingerRun)); - pingerThread.Name = "Ivy Pinger Thread"; - pingerThread.Start(); - } - - - } - catch (IOException ex) - { // the client nous a coupé l'herbe sous le pied - Ivy.traceError("IvyClient","I can't send my message to this client. He probably left " + ex.Message); - // invokes the Disconnected applicationListeners - //bus.OnClientDisconnected(new IvyEventArgs(this,id, message )); - // called by the receiver Thread - close(false); - } - } - - /// returns the name of the remote agent. - /// allow an Ivy package class to access the list of regexps at a - /// given time. - /// perhaps we should implement a new IvyApplicationListener method to - /// allow the notification of regexp addition and deletion - /// - - /// sends a direct message to the peer - /// - /// the numeric value provided to the remote client - /// - /// the string that will be match-tested - /// - /// - public void SendDirectMsg(ushort id, string message) - { - try - { - stream.TokenDirectMsg( id, message); - } - catch (IOException ex) - { - Ivy.traceError("IvyClient","I can't send my message to this client. He probably left "+ex.Message); - // first, I'm not a first class IvyClient any more - bus.removeClient(this); - // invokes the Disconnected applicationListeners - //bus.OnClientDisconnected(new IvyEventArgs(this,id, message )); - // should be called by receiver thread - close(false); - } - } - - /// closes the connexion to the peer. - /// - /// should I send Bye message ? - /// the thread managing the socket is stopped - /// - /// - internal void close(bool notify) - { - Ivy.traceProtocol("IvyClient","closing connexion to " + appName); - if (doping ) - { - StopPinging(); - } - if (notify) - try - { - stream.TokenBye(0, "hasta la vista"); - } - catch (IOException ioe) - { - throw new IvyException(ioe.Message); - } - // stop the thread and close the stream - if (clientThread == null) - return; - // Tell Thread to stop. - if (stream != null) - { - try - { - stream.Close(); // should stop the Reading Client Thread - } - catch (IOException ioe) - { - throw new IvyException(ioe.Message); - } - //socket.Close(); // pris en charge par stream ( NetWorkStream ) - stream = null; - } - // Potential dead lok when thread issue ClientDisconnected event - //if (Thread.CurrentThread != clientThread && (clientThread != null)) - //{ - // // Wait for Thread to end. - // bool term = clientThread.Join(10000); - // if (!term && (clientThread != null)) clientThread.Abort(); - //} - - clientThread = null; - - - } - - /// sends the substrings of a message to the peer for each matching regexp. - /// - /// the string that will be match-tested - /// - /// the number of messages sent to the peer - /// - /// - internal int sendMsg(String message) - { - int count = 0; - - lock( bindings ) - { - try - { - foreach (IvyBindingBase bind in bindings.Values) - { - string[] args = bind.Match(message); - if (stream != null && args != null) - { - stream.TokenMsg(bind.Key, args); - count++; - } - } - } - catch (IOException ex) - { - Ivy.traceError("IvyClient","I can't send my message to this client. He probably left " + ex.Message); - // first, I'm not a first class IvyClient any more - bus.removeClient(this); - // invokes the Disconnected applicationListeners - // in the receiver thread - close(false); - } - - - } - return count; - } - - /// compares two peers the id is the couple (host,service port). - /// - /// the other peer - /// - /// true if the peers are similir. This should not happen, it is bad - /// © ® (tm) - /// - /// - internal bool sameClient(IvyClient clnt) - { - return (appPort != 0 && appPort == clnt.appPort) && (RemoteAddress == clnt.RemoteAddress); - } - - /// the code of the thread handling the incoming messages. - /// - private void Run() - { - Ivy.traceProtocol("IvyClient","Connected from " + RemoteAddress + ":" + RemotePort); - - Ivy.traceProtocol("IvyClient","Thread started"); - - bool running = true; - while ( running && (stream != null) ) - { - try - { - if ( stream.receiveMsg() ) - { - // early stop during readLine() - if (doping && (pingerThread != null)) - pingerThread.Abort(); - } - else - { - Ivy.traceProtocol("IvyClient","receiveMsg false ! leaving the thread"); - running = false; - break; - } - } - catch ( ObjectDisposedException ex ) - { - Ivy.traceError("IvyClient", "socket closed "+ex.Message ); - running = false; - break; - } - catch (IvyException ie) - { - Ivy.traceError("IvyClient","socket closed IvyException" + ie.Message); - running = false; - break; - } - catch (SocketException se) - { - Ivy.traceError("IvyClient", "socket closed "+se.Message ); - running = false; - break; - } - catch (IOException ex) - { - if ( ex.InnerException is SocketException ) - { - Ivy.traceProtocol("IvyClient", "socket closed" ); - - } - else - { - Ivy.traceError("IvyClient","abnormally Disconnected from " + RemoteAddress + ":" + RemotePort); - } - running = false; - break; - } - } - Ivy.traceProtocol("IvyClient","normally Disconnected from " + appName); - Ivy.traceProtocol("IvyClient","Thread stopped"); - // invokes the Disconnected applicationListeners - bus.OnClientDisconnected(new IvyEventArgs(this,0, "" )); - // first, I'm not a first class IvyClient any more - if (stream != null) - { - stream.Close(); - stream = null; - } - bus.removeClient(this); - - } - void IvyProtocol.Close() - { - // never call in this side - } - bool IvyProtocol.receiveMsg() - { - // nerver call in this side - return false; - } - void IvyProtocol.TokenDie(ushort id, string arg) - { - Ivy.traceProtocol("IvyClient","received die Message from " + appName + "Raison: "+ arg); - // invokes the die applicationListeners - IvyDieEventArgs ev = new IvyDieEventArgs(this, id, arg); - bus.OnDie(ev); - // first, I'm not a first class IvyClient any more - bus.removeClient(this); - // makes the bus die - bus.Stop(); - close(false); - if (ev.ForceExit) -#if (PocketPC) - System.Windows.Forms.Application.Exit(); -#else - System.Environment.Exit(0); -#endif - } - void IvyProtocol.TokenBye(ushort err, string arg) - { - // the peer quits - Ivy.traceProtocol("IvyClient","received bye Message from " + appName + "Raison: "+ arg); - // first, I'm not a first class IvyClient any more - //bus.removeClient(this); // this is done in the receive thread terminaison!! - // invokes the disconnect applicationListeners - //bus.FireClientDisconnected(this); done in Running Thread - close(false); // will fire disconnected - } - - void IvyProtocol.TokenAddBinding(BindingType type, ushort id, string expression) - { - - if (type == BindingType.Regexp && !bus.CheckRegexp(expression)) - { - bus.OnClientFilterBinding(new IvyEventArgs(this, id, expression )); - return; - } - IvyBindingBase bind = null; - try - { - switch (type) - { - case BindingType.Regexp: - bind = new IvyBindingRegexp(id, expression); - break; - case BindingType.Simple: - bind = new IvyBindingSimple(id, expression); - break; - } - lock (bindings) - { - bindings.Add(id, bind); - } - - bus.OnClientAddBinding(new IvyEventArgs(this, id, expression)); - - } - catch (ArgumentException ex) - { - throw new IvyException("binding expression error " + ex.Message); - } - - } - void IvyProtocol.TokenDelBinding(ushort id) - { - lock( bindings ) - { - try - { - IvyBindingBase bind = bindings[id]; - bus.OnClientRemoveBinding(new IvyEventArgs(this, bind.Key, bind.Expression)); - bindings.Remove(id); - } - catch (KeyNotFoundException ex) - { - Ivy.traceError("IvyClient","DelBinding " + ex.Message); - } - } - } - void IvyProtocol.TokenMsg(ushort id, string[] args) - { - bus.OnMessage(new IvyMessageEventArgs(this, id, args)); - } - void IvyProtocol.TokenError(ushort id, string arg) - { - bus.OnError(new IvyEventArgs(this, id, arg)); - Ivy.traceError("IvyClient","Error msg " + id + " " + arg); - } - void IvyProtocol.TokenApplicationId(ushort id, string arg) - { - clientId = arg; - if ( clientPriority != id ) - { - clientPriority = id; - bus.SortClients(); - } - } - void IvyProtocol.TokenEndRegexp() - { - /* - * the peer is perhaps not ready to handle this message - * an assymetric processing should be written - */ - if (bus.ReadyMessage != null) - sendMsg(bus.ReadyMessage); - bus.OnClientConnected(new IvyEventArgs(this, 0, "")); - } - void IvyProtocol.TokenStartRegexp(ushort id, string arg) - { - appName = arg; - appPort = id; - if (bus.checkConnected(this)) - { - close(false); - throw new IvyException("Rare ! A concurrent connect occured"); - } - - } - void IvyProtocol.TokenDirectMsg(ushort id, string arg) - { - bus.OnDirectMessage(new IvyEventArgs(this,id,arg)); - } - void IvyProtocol.TokenPing(string arg) - { - // I receive a ping. I can answer a pong. - Ivy.traceProtocol("IvyClient","Ping msg from " + appName + " : " + arg ); - stream.TokenPong(arg); - } - void IvyProtocol.TokenPong(string arg) - { - Ivy.traceProtocol("IvyClient","Ping msg from " + appName + " : " + arg); - } - - - - public override String ToString() - { - return "IvyClient " + bus.appName + ":" + appName; - } - - /* is the Pinging Thread Runninng */ - internal bool isPinging; - - private void PingerRun() - { - isPinging = true; - Ivy.traceProtocol("IvyClient","Pinger Thread started"); - while (isPinging) - { - try - { - Thread.Sleep(PINGTIMEOUT); - stream.TokenPing("are you here ?"); - } - catch (ThreadAbortException ie) - { - Ivy.traceError("IvyClient","Pinger Thread killed "+ie.Message); - } - } - Ivy.traceProtocol("IvyClient","Pinger Thread stopped"); - } - public virtual void StopPinging() - { - isPinging = false; - //pingerThread.Interrupt(); - pingerThread.Abort(); - } - - #region IDisposable Members - - //Implement IDisposable. - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - // Free other state (managed objects). - } - // Free your own state (unmanaged objects). - // Set large fields to null. - if (stream != null) - { - stream.Close(); - stream = null; - } - } - - // Use C# destructor syntax for finalization code. - ~IvyClient() - { - // Simply call Dispose(false). - Dispose(false); - } - - #endregion - } -} \ No newline at end of file -- cgit v1.1