<repo_name>luyikk/IFS<file_sep>/IFSClient/IFSClient.cs
﻿using IFSServ;
using Netx.Client;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace IFS
{
    public class IFSClient
    {
        public NetxSClient Client { get; }
        public INetxSClientBuilder INetxtBuilder { get; }
        private IFSService service { get; }
        public IFSClient(string host, int port, string key)
        {
            INetxtBuilder = new NetxSClientBuilder()
             .ConfigConnection(p => //配置服务器IP
             {
                 p.Host = host;
                 p.Port = port;
                 p.VerifyKey = key;
                 p.ServiceName = "IFServ";
             })
             .ConfigSessionStore(() => new Netx.Client.Session.SessionFile());

            Client = INetxtBuilder.Build();

          
        }
        
        public IFSService GetFSService()=> Client.Get<IFSService>();     

    }
}
<file_sep>/ISFSrv/IFSOption.cs
﻿using System;
using System.Collections.Generic;
using System.Text;

namespace IFSServ
{
    public class IFSOption
    {
        public string Path { get; set; } = "./file";
    }
}
<file_sep>/ISFSrv/Program.cs
﻿using System;
using Netx.Service.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using IFSServ.Interface;

namespace IFSServ
{
    class Program
    {
        static void Main(string[] args)
        {
            var server = new NetxServBuilder()
                .ConfigBase(p =>
                {
                    p.VerifyKey = "123123";
                    p.ServiceName = "IFServ";
                })
                .ConfigNetWork(p => p.Port = 1322)
                .RegisterDescriptors(p =>
                {
                    p.Configure<IFSOption>(option =>
                    {
                        option.Path = "./file";
                    });
                    p.AddSingleton<IUserVerification, UserVerification>();
                })
                .RegisterService(Assembly.GetExecutingAssembly())
                .Build();

            server.Start();


            while (true)
            {
                Console.ReadLine();
            }
        }
    }
}
<file_sep>/IFSClient/IFSService.cs
﻿using Netx;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace IFSServ
{
    [Build]
    public interface IFSService
    {
        [TAG(1000)]
        Task<bool> LogOn(string username, string password);

        [TAG(1001)]
        Task<List<(string filename, string fullname, byte type, byte[] data)>> GetFs(string path);

        [TAG(1002)]
        Task<bool> Del(string filename);
    }
}
<file_sep>/ISFSrv/Interface/IUserVerification.cs
﻿using System;
using System.Collections.Generic;
using System.Text;

namespace IFSServ.Interface
{
    public interface IUserVerification
    {
        bool Verification(string username, string password);
    }

    public class UserVerification : IUserVerification
    {
        public bool Verification(string username, string password)
        {
            return true;
        }
    }
}
<file_sep>/ISFSrv/Interface/IFileActor.cs
﻿using Netx;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace IFSServ
{
    [Build]
    public interface IFileActor
    {
        [TAG(1)]
        Task<List<(string filename, string fullname, byte type, byte[] data)>> GetFileList(string basepath, string path);

        [TAG(2)]
        Task<bool> Del(string file);
    }
}
<file_sep>/Unit.serv/UnitFileInfoGet.cs
using IFS;
using IFSServ;
using IFSServ.Interface;
using Microsoft.Extensions.DependencyInjection;
using Netx.Actor;
using Netx.Service.Builder;
using System;
using System.Reflection;
using Xunit;
using Xunit.Abstractions;

namespace Unit.serv
{
    public class UnitFileInfoGet
    {
       
        private readonly ITestOutputHelper output;
        public UnitFileInfoGet(ITestOutputHelper tempOutput)
        {
            output = tempOutput;  
        }


        [Fact]
        public async void TestServer()
        {
            var server = new NetxServBuilder()
               .ConfigBase(p =>
               {
                   p.VerifyKey = "123123";
                   p.ServiceName = "IFServ";
               })
               .ConfigNetWork(p => p.Port = 1322)
               .RegisterDescriptors(p =>
               {
                   p.Configure<IFSOption>(option =>
                   {
                       option.Path = "./";
                   });
                   p.AddSingleton<IUserVerification, UserVerification>();
               })
               .RegisterService(typeof(IFSController).Assembly)
               .Build();

            server.Start();

            var client = new IFSClient("127.0.0.1", 1322, "123123");
            var service = client.GetFSService();
            await service.LogOn("username", "password");
            var dir = await service.GetFs("./");            

            Assert.True(dir.Count > 0);
            server.Stop();
        }

        [Fact]
        public async void TestGetFileInfo()
        {
            var files = await (new IFSActorController()).GetFileList("./", "./");
            Assert.NotNull(files);
            output.WriteLine($"file length:{files.Count}");            
        }

    }
}
<file_sep>/ISFSrv/IFSController.cs
﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Netx.Loggine;
using Netx.Service;
using System.IO;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using IFSServ.Interface;

namespace IFSServ
{
    public class IFSController : AsyncController, IFSService
    {
        public ILog Log { get; }
        public IFSOption Option { get; }
        public string BasePath => Path.GetFullPath(Option.Path);
        public IUserVerification Verification { get; }
        public bool LogIn { get; private set; }

        public IFSController(IUserVerification verification, IOptions<IFSOption> options, ILogger<IFSController> logger)
        {
            Log = new DefaultLog(logger);
            Option = options.Value;

            Verification = verification;

            if (!Directory.Exists(Option.Path))
            {
                Log.Info($"Create base path {Option.Path}");
                Directory.CreateDirectory(Option.Path);
            }
        }
        public Task<bool> LogOn(string username, string password)
        {
            LogIn = Verification.Verification(username, password);
            return Task.FromResult(LogIn);
        }

        public async Task<bool> Del(string filename)
        {
            var ls = Path.GetFullPath(filename, BasePath);
            checkPathPermission(ls);
            return await Actor<IFileActor>().Del(ls);
        }

        public async Task<List<(string filename, string fullname, byte type, byte[] data)>> GetFs(string path)
        {
            checkLogIN();
            var ls = Path.GetFullPath(path, BasePath);
            checkPathPermission(ls);
            return await Actor<IFileActor>().GetFileList(BasePath, ls);

        } 

        private void checkPathPermission(string path)
        {
            if (path.IndexOf(BasePath) != 0)
                throw new IOException("Permission denied");
        }

        private void checkLogIN()
        {
            if (!LogIn)
                throw new Exception("Permission denied");
        }
      
    }
}
<file_sep>/ISFSrv/IFSActorController.cs
﻿using Netx.Actor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace IFSServ
{
    //12311
    [ActorOption(maxQueueCount: 1500, ideltime: 3000)]
    public class IFSActorController : ActorController, IFileActor
    {
        
        [Netx.Actor.Open(OpenAccess.Internal)]
        public Task<List<(string filename, string fullname, byte type, byte[] data)>> GetFileList(string basepath,string path)
        {
            var files = from p in GetFileInfos(path)
                        select
                        (
                            p.Name,
                            Path.GetRelativePath(basepath, p.FullName),
                            p is FileInfo ? (byte)0 : (byte)1,
                            p is FileInfo ? GetMD5HashFromFile(p.FullName) : null
                        );


            return Task.FromResult(files.ToList());
        }

        private FileSystemInfo[] GetFileInfos(string path)
        {
            DirectoryInfo directoryInfo = new DirectoryInfo(path);

            if (!directoryInfo.Exists)
            {
                throw new IOException($"not find path:{path}");
            }
            else
            {                              
                return directoryInfo.GetFileSystemInfos();
            }
        }

        [Netx.Actor.Open(OpenAccess.Internal)]
        public Task<bool> Del(string file)
        {
            if (File.Exists(file))
            {
                File.Delete(file);
                return Task.FromResult(true);
            }

            return Task.FromResult(false);
        }



        public byte[] GetMD5HashFromFile(string fileName)
        {
            using (FileStream file = new FileStream(fileName, System.IO.FileMode.Open,FileAccess.Read))
            {
                MD5 md5 = new MD5CryptoServiceProvider();

                return md5.ComputeHash(file);   
            }
        }


    }
}
