diff options
Diffstat (limited to 'CSharp/Ivy')
-rw-r--r-- | CSharp/Ivy/IvyPPC/IvyClient.cs | 198 |
1 files changed, 67 insertions, 131 deletions
diff --git a/CSharp/Ivy/IvyPPC/IvyClient.cs b/CSharp/Ivy/IvyPPC/IvyClient.cs index 9e72e92..82e29bb 100644 --- a/CSharp/Ivy/IvyPPC/IvyClient.cs +++ b/CSharp/Ivy/IvyPPC/IvyClient.cs @@ -7,6 +7,8 @@ namespace IvyBus {
using System;
using System.Collections;
+ using System.Collections.Specialized;
+ using System.Collections.Generic;
using System.Threading;
using System.Text;
using System.IO;
@@ -22,20 +24,24 @@ namespace IvyBus /// die messages, direct messages, add or remove regexps, or quit. A thread is
/// created for each remote client.
/// </remarks>
- public class IvyClient
+ public class IvyClient : IvyProtocolInterface, IComparable<IvyClient>
{
- public class IvyClientPriority : IComparer
- {
+ //public class IvyClientPriority : IComparer
+ //{
- // Calls CaseInsensitiveComparer.Compare with the parameters reversed.
- int IComparer.Compare( Object x, Object y )
- {
- IvyClient c1 = (IvyClient)x;
- IvyClient c2 = (IvyClient)y;
- return( c2.clientPriority - c1.clientPriority );
- }
+ // // Calls CaseInsensitiveComparer.Compare with the parameters reversed.
+ // int IComparer.Compare( Object x, Object y )
+ // {
+ // IvyClient c1 = (IvyClient)x;
+ // IvyClient c2 = (IvyClient)y;
+ // return( c2.clientPriority - c1.clientPriority );
+ // }
- }
+ //}
+ public int CompareTo(IvyClient y)
+ {
+ return (y.clientPriority - clientPriority);
+ }
public String ApplicationName
{
@@ -86,7 +92,7 @@ namespace IvyBus private Ivy bus;
private Socket socket;
- private Hashtable bindings;
+ private Dictionary<ushort,IvyBindingBase> bindings;
private int appPort;
private string clientId; /* an unique ID for each IvyClient */
private int clientPriority; /* client priority */
@@ -94,43 +100,50 @@ namespace IvyBus private bool peerCalling;
private volatile bool running = false;
private volatile Thread clientThread; // volatile to ensure the quick communication
- private static bool doping = (ConfigurationSettings.AppSettings["IVY_PING"] != null);
+ private static bool doping = Properties.Settings.Default.IvyPing;
private const int PINGTIMEOUT = 5000;
private volatile Thread pingerThread;
// protected variables
internal String appName;
- internal IvyTCPStreamV4 stream;
-
+ internal IvyTCPStream stream;
+
internal IvyClient(Ivy bus, Socket socket, string appname)
{
- bindings = Hashtable.Synchronized(new Hashtable());
+ bindings = new Dictionary<ushort,IvyBindingBase>();
appName = appname;
appPort = 0;
this.bus = bus;
this.socket = socket;
socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, 1 );
- stream = new IvyTCPStreamV4( socket );
+
+ if ( Properties.Settings.Default.IvyProtocolVersion == 4 )
+ stream = new IvyTCPStreamV4( socket, this );
+ else
+ stream = new IvyTCPStreamV3(socket, this);
clientPriority = Ivy.DEFAULT_PRIORITY;
- stream.sendApplicationId(bus.applicationPriority, bus.AppId);
+ 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.sendStartRegexp( bus.applicationPort, bus.appName );
+ stream.TokenStartRegexp( bus.applicationPort, bus.appName );
// sends our regexps to the peer
- lock( bus.bindings.SyncRoot )
+ lock( bus.bindings )
{
foreach (Ivy.ApplicationBinding bind in bus.bindings.Values )
{
- stream.sendBinding(bind);
+ if ( bind.type == Ivy.BindingType.BindSimple )
+ stream.TokenAddBinding(bind.key,bind.regexp);
+ else
+ stream.TokenAddRegexp(bind.key, bind.regexp);
}
}
- stream.sendEndRegexp();
+ stream.TokenEndRegexp();
// 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));
@@ -158,11 +171,11 @@ namespace IvyBus /// <param name='message'>the string that will be match-tested
///
/// </param>
- public void sendDirectMsg(int id, string message)
+ public void sendDirectMsg(ushort id, string message)
{
try
{
- stream.sendDirectMsg( id, message);
+ stream.TokenDirectMsg( id, message);
}
catch (IOException e)
{
@@ -196,7 +209,7 @@ namespace IvyBus stopPinging();
}
if (notify)
- stream.sendBye("hasta la vista");
+ stream.TokenBye(0,"hasta la vista");
stopListening();
// bus.clientDisconnect(this);
// in_stream close in the thread
@@ -220,15 +233,15 @@ namespace IvyBus {
int count = 0;
- lock( bindings.SyncRoot )
+ lock( bindings )
{
IvyBindingSimple.Prepare( message );
foreach (IvyBindingBase bind in bindings.Values )
{
- IvyArgument args = bind.Match(message);
+ string[] args = bind.Match(message);
if (args!=null)
{
- stream.sendMsg(bind.key, args);
+ stream.TokenMsg(bind.key, args);
count++;
}
}
@@ -270,9 +283,6 @@ namespace IvyBus /// </summary>
private void Run()
{
- IvyTCPStreamV4.MessageType type;
- int id;
- byte[] data;
int length;
try
@@ -290,12 +300,11 @@ namespace IvyBus {
try
{
- if ( stream.receiveMsg(out type, out id, out data ) )
+ if ( stream.receiveMsg() )
{
- // early stop during readLine()
+ // early stop during readLine() //TODO why PinThread Interrupt
if (doping && (pingerThread != null))
pingerThread.Interrupt();
- DispatchMsg(type, id, data);
}
else
{
@@ -352,15 +361,15 @@ namespace IvyBus bus.removeClient(this);
}
-
-
- private void recvDie( int id, string arg )
+
+
+ public void TokenDie(ushort id, string arg)
{
traceDebug("received die Message from " + appName);
// first, I'm not a first class IvyClient any more
bus.removeClient(this);
// invokes the die applicationListeners
- bool dontkillapp = bus.FireDie(this, id);
+ bool dontkillapp = bus.FireDie(this, id, arg);
// makes the bus die
bus.stop();
try
@@ -374,7 +383,7 @@ namespace IvyBus if ( !dontkillapp )
Environment.Exit( -1 );
}
- private void recvBye( int id, string arg )
+ public void TokenBye(ushort err, string arg)
{
// the peer quits
traceDebug("received bye Message from " + appName + "Raison: "+ arg);
@@ -391,14 +400,14 @@ namespace IvyBus throw new IvyException(ioe.Message);
}
}
- private void recvAddRegexp( int id, string regexp )
+ public void TokenAddRegexp(ushort id, string regexp)
{
if (bus.CheckRegexp(regexp))
{
try
{
IvyBindingRegexp bind = new IvyBindingRegexp(id,regexp);
- lock( bindings.SyncRoot )
+ lock( bindings )
{
bindings.Add( id, bind);
}
@@ -414,23 +423,14 @@ namespace IvyBus traceDebug("regexp Warning exp='" + regexp + "' can't match removing from " + appName);
}
}
- private void recvDelRegexp( int id, string arg )
- {
- lock( bindings.SyncRoot )
- {
- IvyBindingBase bind = (IvyBindingBase) bindings[id];
- bus.FireClientRemoveBinding( this, bind.expression );
- bindings.Remove(id);
- }
-
- }
- private void recvAddBinding( int id, string expression )
+
+ public void TokenAddBinding(ushort id, string expression)
{
try
{
IvyBindingSimple bind = new IvyBindingSimple(id, expression);
- lock( bindings.SyncRoot )
+ lock( bindings )
{
bindings.Add( id, bind);
}
@@ -442,24 +442,24 @@ namespace IvyBus }
}
- private void recvDelBinding( int id, string arg )
+ public void TokenDelBinding(ushort id)
{
- lock( bindings.SyncRoot )
+ lock( bindings )
{
IvyBindingBase bind = (IvyBindingBase) bindings[id];
bus.FireClientRemoveBinding( this, bind.expression );
bindings.Remove(id);
}
}
- private void recvMsg( int id, byte[] arg )
+ public void TokenMsg(ushort id, string[] arg)
{
- bus.callCallback(this, id, arg);
+ bus.FireCallback(this, id, arg);
}
- private void recvError( int id, string arg )
+ public void TokenError(ushort id, string arg)
{
traceDebug("Error msg " + id + " " + arg);
}
- private void recvApplicationId( int id, string arg )
+ public void TokenApplicationId(ushort id, string arg)
{
clientId = arg;
if ( clientPriority != id )
@@ -468,7 +468,7 @@ namespace IvyBus bus.SortClients();
}
}
- private void recvEndRegexp( int id, string arg )
+ public void TokenEndRegexp()
{
bus.FireClientConnected(this);
/*
@@ -478,7 +478,7 @@ namespace IvyBus if (bus.ready_message != null)
sendMsg(bus.ready_message);
}
- private void recvStartRegexp( int id, string arg )
+ public void TokenStartRegexp(ushort id, string arg)
{
appName = arg;
appPort = id;
@@ -496,85 +496,21 @@ namespace IvyBus }
}
- private void recvDirectMsg( int id, byte[] arg )
+ public void TokenDirectMsg(ushort id, string arg)
{
bus.FireDirectMessage(this, id, arg );
}
- private void recvPing( int id, byte[] arg )
+ public void TokenPing(string arg)
{
// I receive a ping. I can answer a pong.
- traceDebug("Ping msg from " + appName + " : " + Encoding.ASCII.GetString( arg) );
- stream.sendPong(arg);
+ traceDebug("Ping msg from " + appName + " : " + arg );
+ stream.TokenPong(arg);
}
- private void recvPong( int id, byte[] arg )
+ public void TokenPong(string arg)
{
traceDebug("Ping msg from " + appName + " : " + arg);
}
- private void DispatchMsg(IvyTCPStreamV4.MessageType msgType, int msgId, byte[] msgData)
- {
- string strarg = Encoding.ASCII.GetString( msgData );
- switch (msgType)
- {
- case IvyTCPStreamV4.MessageType.Die:
- recvDie( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.Bye:
- recvBye( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.AddRegexp:
- recvAddRegexp( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.DelRegexp:
- recvDelRegexp( msgId, strarg );
- break;
- case IvyTCPStreamV4.MessageType.AddBinding:
- recvAddBinding( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.DelBinding:
- recvDelBinding( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.EndRegexp:
- recvEndRegexp( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.Msg:
- recvMsg( msgId, msgData );
- break;
-
- case IvyTCPStreamV4.MessageType.Pong:
- recvPong( msgId, msgData );
- break;
-
- case IvyTCPStreamV4.MessageType.Ping:
- recvPing( msgId, msgData );
- break;
-
- case IvyTCPStreamV4.MessageType.Error:
- recvError( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.StartRegexp:
- recvStartRegexp( msgId, strarg );
- break;
-
- case IvyTCPStreamV4.MessageType.DirectMsg:
- recvDirectMsg( msgId, msgData );
- break;
- case IvyTCPStreamV4.MessageType.ApplicationId:
- recvApplicationId( msgId, strarg );
- break;
- default:
- throw new IvyException("protocol error, unknown message type " + msgType);
-
- }
- }
-
@@ -599,7 +535,7 @@ namespace IvyBus try
{
Thread.Sleep(new TimeSpan(10000 * PINGTIMEOUT));
- stream.sendPing("are you here ?");
+ stream.TokenPing("are you here ?");
}
catch (ThreadInterruptedException ie)
{
|