예제 #1
0
파일: Client.cs 프로젝트: Cocotus/XTMF
        public void ClientMain()
        {
            TcpClient connection = null;
            bool done = false;
            try
            {
                connection = new TcpClient( this.Address, this.Port );
                var networkStream = connection.GetStream();
                new Thread( delegate()
                    {
                        try
                        {
                            BinaryReader reader = new BinaryReader( networkStream );
                            BinaryFormatter inputFormat = new BinaryFormatter();
                            // we need some connection every 60 minutes, the host should be trying to request progress
                            networkStream.ReadTimeout = Timeout.Infinite;
                            while ( !done || this.Exit )
                            {
                                var msg = new Message( (MessageType)reader.ReadInt32() );
                                switch ( msg.Type )
                                {
                                    case MessageType.RequestProgress:
                                        {
                                            msg.Type = MessageType.PostProgess;
                                            this.Messages.Add( msg );
                                        }
                                        break;

                                    case MessageType.ReturningResource:
                                        {
                                            var name = reader.ReadString();
                                            bool exists = reader.ReadBoolean();
                                            object data = null;
                                            if ( exists )
                                            {
                                                data = inputFormat.Deserialize( reader.BaseStream );
                                            }
                                            Result res = new Result() { Name = name, Data = data };
                                            msg.Data = res;
                                            this.Messages.Add( msg );
                                        }
                                        break;

                                    case MessageType.PostCancel:
                                        {
                                            this.Messages.Add( msg );
                                        }
                                        break;

                                    case MessageType.SendModelSystem:
                                        {
                                            var length = reader.ReadInt32();
                                            byte[] data = new byte[length];
                                            var soFar = 0;
                                            while ( soFar < length )
                                            {
                                                soFar += reader.Read( data, soFar, length - soFar );
                                            }
                                            msg.Data = data;
                                            this.Messages.Add( msg );
                                        }
                                        break;

                                    case MessageType.Quit:
                                        {
                                            done = true;
                                            this.Exit = true;
                                            Console.WriteLine( "Exiting." );
                                        }
                                        break;

                                    case MessageType.SendCustomMessage:
                                        {
                                            // Time to receive a new custom message
                                            var number = reader.ReadInt32();
                                            var length = reader.ReadInt32();
                                            var buff = new byte[length];
                                            MemoryStream buffer = new MemoryStream( buff );
                                            int soFar = 0;
                                            while ( soFar < length )
                                            {
                                                soFar += reader.Read( buff, soFar, length - soFar );
                                            }
                                            this.Messages.Add( new Message( MessageType.ReceiveCustomMessage,
                                                new ReceiveCustomMessageMessage()
                                                {
                                                    CustomMessageNumber = number,
                                                    Stream = buffer
                                                } ) );
                                        }
                                        break;

                                    default:
                                        {
                                            // We don't know how to deal with this
                                            done = true;
                                            this.Exit = true;
                                            Console.WriteLine( "Came across a message number " + msg.Type + " not sure what to do with it.  Exiting." );
                                        }
                                        break;
                                }
                                Thread.MemoryBarrier();
                            }
                        }
                        catch ( IOException )
                        {
                            done = true;
                            Thread.MemoryBarrier();
                            this.Exit = true;
                            Console.WriteLine( "Host has disconnected Client" );
                            Environment.Exit( 0 );
                        }
                        catch ( Exception e )
                        {
                            done = true;
                            Console.WriteLine( "Client exception" );
                            Console.WriteLine( e.Message );
                            Console.WriteLine( e.StackTrace );
                        }
                        finally
                        {
                            Console.WriteLine("Client reader has exited.");
                            connection.Close();
                            done = true;
                            this.Exit = true;
                            Thread.MemoryBarrier();
                        }
                    } ).Start();
                BinaryWriter writer = new BinaryWriter( networkStream );
                BinaryFormatter outputFormat = new BinaryFormatter();
                networkStream.WriteTimeout = 20000;
                while ( !done && !this.Exit )
                {
                    var message = this.Messages.GetMessageOrTimeout( 200 );
                    Thread.MemoryBarrier();
                    if ( !done && message != null )
                    {
                        var exit = ProcessMessage( writer, outputFormat, message );
                        if ( exit )
                        {
                            done = true;
                        }
                    }
                }
            }
            catch ( Exception e )
            {
                Console.WriteLine( e.Message );
                Console.WriteLine( e.StackTrace );
            }
            finally
            {
                if ( connection != null )
                {
                    connection.Close();
                }
                done = true;
            }
            done = true;
            this.Exit = true;
        }
예제 #2
0
파일: Client.cs 프로젝트: Cocotus/XTMF
        private bool ProcessMessage(BinaryWriter writer, BinaryFormatter outputFormat, Message message)
        {
            switch ( message.Type )
            {
                case MessageType.PostComplete:
                    {
                        writer.Write( (Int32)MessageType.PostComplete );
                    }
                    break;

                case MessageType.PostResource:
                    {
                        var data = message.Data as Result;
                        writer.Write( data.Name );
                        outputFormat.Serialize( writer.BaseStream, data.Data );
                    }
                    break;

                case MessageType.PostProgess:
                    {
                        writer.Write( (Int32)MessageType.PostProgess );
                        writer.Write( this.Progress );
                        writer.Flush();
                    }
                    break;

                case MessageType.RequestResource:
                    {
                        var dr = message.Data as DelayedResult;
                        this.ResourceRequests.AddLast( dr );
                        writer.Write( (Int32)MessageType.RequestResource );
                        writer.Write( dr.Name );
                        writer.Flush();
                    }
                    break;

                case MessageType.ReturningResource:
                    {
                        var result = message.Data as Result;
                        DelayedResult toRemove = null;
                        foreach ( var delayed in this.ResourceRequests )
                        {
                            if ( delayed.Name == result.Name )
                            {
                                toRemove = delayed;
                                delayed.Data = result.Data;
                                delayed.Lock.Release();
                                break;
                            }
                        }
                        if ( toRemove != null )
                        {
                            ResourceRequests.Remove( toRemove );
                        }
                    }
                    break;

                case MessageType.PostCancel:
                    {
                        var ms = this.CurrentRunningModelSystem;
                        // if we don't have a model system then we are done
                        if ( ms == null ) break;
                        try
                        {
                            // try to cancel the model system
                            ms.ExitRequest();
                        }
                        catch
                        {
                        }
                    }
                    break;

                case MessageType.SendModelSystem:
                    {
                        try
                        {
                            var mssBuff = message.Data as byte[];
                            IModelSystemStructure mss = null;
                            using ( MemoryStream memory = new MemoryStream() )
                            {
                                memory.Write( mssBuff, 0, mssBuff.Length );
                                memory.Position = 0;
                                mss = ModelSystemStructure.Load( memory, this.Configuration );
                            }

                            if ( this.ModelSystemThread != null && this.ModelSystemThread.IsAlive )
                            {
                                try
                                {
                                    this.ModelSystemThread.Abort();
                                }
                                catch
                                {
                                }
                            }
                            // now that the other thread is going to end
                            // we can now go and start generating ourselves
                            // in another run thread
                            ( this.ModelSystemThread =
                                new Thread( ModelSystemStartup ) ).Start( mss );
                        }
                        catch ( Exception e )
                        {
                            Console.WriteLine( e.ToString() );
                            return true;
                        }
                    }
                    break;

                case MessageType.SendCustomMessage:
                    {
                        var msg = message.Data as SendCustomMessageMessage;
                        int msgNumber = msg.CustomMessageNumber;
                        int length = 0;
                        var failed = false;
                        byte[] buffer = null;
                        Action<object, Stream> customConverter;
                        bool getConverter = false;
                        lock ( this )
                        {
                            getConverter = this.CustomSenders.TryGetValue( msgNumber, out customConverter );
                        }
                        if ( getConverter )
                        {
                            using ( MemoryStream mem = new MemoryStream( 0x100 ) )
                            {
                                try
                                {
                                    customConverter( msg.Data, mem );
                                    mem.Position = 0;
                                    buffer = mem.ToArray();
                                    length = buffer.Length;
                                }
                                catch
                                {
                                    failed = true;
                                }
                            }
                        }
                        writer.Write( (Int32)MessageType.SendCustomMessage );
                        writer.Write( (Int32)msg.CustomMessageNumber );
                        writer.Write( (Int32)length );
                        if ( !failed )
                        {
                            writer.Write( buffer, 0, length );
                            buffer = null;
                        }
                    }
                    break;

                case MessageType.ReceiveCustomMessage:
                    {
                        var msg = message.Data as ReceiveCustomMessageMessage;
                        var customNumber = msg.CustomMessageNumber;
                        Func<Stream, object> customConverter;
                        bool getConverted = false;
                        lock ( this )
                        {
                            getConverted = this.CustomReceivers.TryGetValue( customNumber, out customConverter );
                        }
                        if ( getConverted )
                        {
                            using ( var stream = msg.Stream )
                            {
                                try
                                {
                                    object output = customConverter( stream );
                                    List<Action<object>> handlers;
                                    if ( this.CustomHandlers.TryGetValue( msg.CustomMessageNumber, out handlers ) )
                                    {
                                        foreach ( var handler in handlers )
                                        {
                                            try
                                            {
                                                handler( output );
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine( e.Message + "\r\n" + e.StackTrace );
                                            }
                                        }
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                    break;

                default:
                    {
                        // FAIL!
                        Console.WriteLine( "Processing a message of type " + message.Type + " and we didn't know what to do with it." );
                        return true;
                    }
            }
            return false;
        }