Kupalasa njinga kwapamwamba kapena pulogalamu ya kasitomala-seva kutengera C# .Net framework

kulowa

Zonse zidayamba pomwe mnzanga adandiuza kuti ndipange kawebusayiti kakang'ono. Izo zimayenera kukhala zinazake ngati tinder, koma kwa IT hangout. Magwiridwe ake ndi osavuta, mumalembetsa, lembani mbiri ndikupita ku mfundo yayikulu, mwachitsanzo, kupeza wolumikizirana ndikukulitsa kulumikizana kwanu ndikupanga mabwenzi atsopano.

Pano ndiyenera kudodometsa ndikunena pang'ono za ine ndekha, kuti m'tsogolo zidziwike bwino chifukwa chake ndinatengera izi pa chitukuko.

Pakalipano ndili ndi udindo wa Technical Artist mu studio yamasewera, chidziwitso changa cha C # chinakhazikitsidwa polemba zolemba ndi zofunikira za Unity ndipo, kuwonjezera pa izi, kupanga mapulagini a ntchito yotsika ndi zipangizo za android. Kunja kwa dziko lino, sindinasankhebe mwayi woterowo.

Gawo 1. Mafelemu Prototyping

Nditasankha momwe ntchitoyi ingakhalire, ndinayamba kuyang'ana njira zomwe ndingagwiritsire ntchito. Njira yosavuta ndiyo kupeza njira yokonzekera, yomwe, ngati kadzidzi padziko lonse lapansi, mutha kukoka makina athu ndikuyala chinthu chonsecho kuti chitsutsidwe pagulu.
Koma izi sizosangalatsa, sindinawone zovuta ndi malingaliro mu izi, chifukwa chake ndidayamba kuphunzira ukadaulo wapaintaneti ndi njira zolumikizirana nawo.

Phunziroli linayamba ndikuwona zolemba ndi zolemba pa C # .Net. Apa ndinapeza njira zosiyanasiyana zokwaniritsira ntchitoyi. Pali njira zambiri zolumikizirana ndi netiweki, kuchokera kumayankho athunthu monga ASP.Net kapena ntchito za Azure, kuwongolera kulumikizana ndi kulumikizana kwa TcpHttp.

Nditayesa koyamba ndi ASP, ndidazimitsa nthawi yomweyo, m'malingaliro mwanga chinali chisankho chovuta kwambiri pantchito yathu. Sitidzagwiritsa ntchito ngakhale gawo limodzi mwa magawo atatu a kuthekera kwa nsanjayi, kotero ndidapitiliza kufufuza kwanga. Kusankha kudakhala pakati pa TCP ndi Http kasitomala-server. Pano, pa HabrΓ©, ndinapeza nkhani yokhudza multithreaded seva, nditasonkhanitsa ndikuyesa zomwe, ndinaganiza zoganizira za kuyanjana ndi kugwirizana kwa TCP, pazifukwa zina ndinaganiza kuti http sangandilole kuti ndipange njira yothetsera vutoli.

Mtundu woyamba wa seva umaphatikizapo kulumikiza zolumikizira, kutumiza zomwe zili patsamba lawebusayiti, komanso kuphatikizira nkhokwe ya ogwiritsa ntchito. Ndipo poyambira, ndidaganiza zopanga zogwirira ntchito ndi tsambalo, kuti pambuyo pake nditha kumangirira kukonzanso ntchito pa android ndi ios pano.

Nawa malamulo ena
Ulusi waukulu wolandila makasitomala mosalekeza:

using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace ClearServer
{

    class Server
    {
        TcpListener Listener;
        public Server(int Port)
        {
            Listener = new TcpListener(IPAddress.Any, Port);
            Listener.Start();

            while (true)
            {
                TcpClient Client = Listener.AcceptTcpClient();
                Thread Thread = new Thread(new ParameterizedThreadStart(ClientThread));
                Thread.Start(Client);
            }
        }

        static void ClientThread(Object StateInfo)
        {
            new Client((TcpClient)StateInfo);
        }

        ~Server()
        {
            if (Listener != null)
            {
                Listener.Stop();
            }
        }

        static void Main(string[] args)
        {
            DatabaseWorker sqlBase = DatabaseWorker.GetInstance;

            new Server(80);
        }
    }
}

Wosamalira kasitomala yekha:

using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace ClearServer
{
    class Client
    {


        public Client(TcpClient Client)
        {

            string Message = "";
            byte[] Buffer = new byte[1024];
            int Count;
            while ((Count = Client.GetStream().Read(Buffer, 0, Buffer.Length)) > 0)
            {
                Message += Encoding.UTF8.GetString(Buffer, 0, Count);

                if (Message.IndexOf("rnrn") >= 0 || Message.Length > 4096)
                {
                    Console.WriteLine(Message);
                    break;
                }
            }

            Match ReqMatch = Regex.Match(Message, @"^w+s+([^s?]+)[^s]*s+HTTP/.*|");
            if (ReqMatch == Match.Empty)
            {
                ErrorWorker.SendError(Client, 400);
                return;
            }
            string RequestUri = ReqMatch.Groups[1].Value;
            RequestUri = Uri.UnescapeDataString(RequestUri);
            if (RequestUri.IndexOf("..") >= 0)
            {
                ErrorWorker.SendError(Client, 400);
                return;
            }
            if (RequestUri.EndsWith("/"))
            {
                RequestUri += "index.html";
            }

            string FilePath =

quot;D:/Web/TestSite{RequestUri}";

if (!File.Exists(FilePath))
{
ErrorWorker.SendError(Client, 404);
return;
}

string Extension = RequestUri.Substring(RequestUri.LastIndexOf('.'));

string ContentType = "";

switch (Extension)
{
case ".htm":
case ".html":
ContentType = "text/html";
break;
case ".css":
ContentType = "text/css";
break;
case ".js":
ContentType = "text/javascript";
break;
case ".jpg":
ContentType = "image/jpeg";
break;
case ".jpeg":
case ".png":
case ".gif":
ContentType =


quot;image/{Extension.Substring(1)}";
break;
default:
if (Extension.Length > 1)
{
ContentType =


quot;application/{Extension.Substring(1)}";
}
else
{
ContentType = "application/unknown";
}
break;
}

FileStream FS;
try
{
FS = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch (Exception)
{
ErrorWorker.SendError(Client, 500);
return;
}

string Headers =


quot;HTTP/1.1 200 OKnContent-Type: {ContentType}nContent-Length: {FS.Length}nn";
byte[] HeadersBuffer = Encoding.ASCII.GetBytes(Headers);
Client.GetStream().Write(HeadersBuffer, 0, HeadersBuffer.Length);

while (FS.Position < FS.Length)
{
Count = FS.Read(Buffer, 0, Buffer.Length);
Client.GetStream().Write(Buffer, 0, Count);
}

FS.Close();
Client.Close();
}
}
}

Ndipo nkhokwe yoyamba yomangidwa pa SQL yakomweko:

using System;
using System.Data.Linq;
namespace ClearServer
{
    class DatabaseWorker
    {

        private static DatabaseWorker instance;

        public static DatabaseWorker GetInstance
        {
            get
            {
                if (instance == null)
                    instance = new DatabaseWorker();
                return instance;
            }
        }


        private DatabaseWorker()
        {
            string connectionStr = databasePath;
            using (DataContext db = new DataContext(connectionStr))
            {
                Table<User> users = db.GetTable<User>();
                foreach (var item in users)
                {
                    Console.WriteLine(

quot;{item.login} {item.password}");
}
}
}
}
}

Monga mukuonera, Baibuloli limasiyana pang’ono ndi limene lili m’nkhaniyo. M'malo mwake, kungotsitsa masamba kuchokera pafoda pakompyuta ndi nkhokwe zidawonjezedwa pano (zomwe, mwa njira, sizinagwire ntchito mumtunduwu, chifukwa cha kulumikizana kolakwika).

Mutu 2

Nditayesa seva, ndinazindikira kuti iyi ingakhale yankho labwino (spoiler: ayi), chifukwa cha ntchito yathu, motero polojekitiyi idayamba kupeza malingaliro.
Pang'onopang'ono, ma module atsopano adayamba kuwonekera ndipo magwiridwe antchito a seva adakula. Seva ili ndi domeni yoyeserera komanso kubisa kwa kulumikizana kwa ssl.

Kachidindo kakang'ono kamene kakufotokoza malingaliro a seva ndi kukonza kwa makasitomala
Mtundu wosinthidwa wa seva, kuphatikiza kugwiritsa ntchito satifiketi.

using System;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Security;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Policy;
using System.Threading;


namespace ClearServer
{

    sealed class Server
    {
        readonly bool ServerRunning = true;
        readonly TcpListener sslListner;
        public static X509Certificate serverCertificate = null;
        Server()
        {
            serverCertificate = X509Certificate.CreateFromSignedFile(@"C:sslitinder.online.crt");
            sslListner = new TcpListener(IPAddress.Any, 443);
            sslListner.Start();
            Console.WriteLine("Starting server.." + serverCertificate.Subject + "n" + Assembly.GetExecutingAssembly().Location);
            while (ServerRunning)
            {
                TcpClient SslClient = sslListner.AcceptTcpClient();
                Thread SslThread = new Thread(new ParameterizedThreadStart(ClientThread));
                SslThread.Start(SslClient);
            }
            
        }
        static void ClientThread(Object StateInfo)
        {
            new Client((TcpClient)StateInfo);
        }

        ~Server()
        {
            if (sslListner != null)
            {
                sslListner.Stop();
            }
        }

        public static void Main(string[] args)
        {
            if (AppDomain.CurrentDomain.IsDefaultAppDomain())
            {
                Console.WriteLine("Switching another domain");
                new AppDomainSetup
                {
                    ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
                };
                var current = AppDomain.CurrentDomain;
                var strongNames = new StrongName[0];
                var domain = AppDomain.CreateDomain(
                    "ClearServer", null,
                    current.SetupInformation, new PermissionSet(PermissionState.Unrestricted),
                    strongNames);
                domain.ExecuteAssembly(Assembly.GetExecutingAssembly().Location);
            }
            new Server();
        }
    }
}

Komanso kasitomala watsopano yemwe ali ndi chilolezo kudzera pa ssl:

using ClearServer.Core.Requester;
using System;
using System.Net.Security;
using System.Net.Sockets;

namespace ClearServer
{
    public class Client
    {
        public Client(TcpClient Client)
        {
            SslStream SSlClientStream = new SslStream(Client.GetStream(), false);
            try
            {
                SSlClientStream.AuthenticateAsServer(Server.serverCertificate, clientCertificateRequired: false, checkCertificateRevocation: true);
            }
            catch (Exception e)
            {
                Console.WriteLine(
                    "---------------------------------------------------------------------n" +


quot;|{DateTime.Now:g}n|------------n|{Client.Client.RemoteEndPoint}n|------------n|Exception: {e.Message}n|------------n|Authentication failed - closing the connection.n" +
"---------------------------------------------------------------------n");
SSlClientStream.Close();
Client.Close();
}
new RequestContext(SSlClientStream, Client);
}

}
}

Koma popeza seva imagwira ntchito pokhapokha pa kulumikizidwa kwa TCP, ndikofunikira kupanga gawo lomwe lingazindikire zomwe zafunsidwa. Ndinaganiza kuti parser ndi yoyenera pano yomwe idzaphwanya pempho la kasitomala m'magawo osiyana omwe ndingathe kuyanjana nawo kuti ndipatse kasitomala mayankho ofunikira.

wofotokozera

using ClearServer.Core.UserController;
using ReServer.Core.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace ClearServer.Core.Requester
{
    public class RequestContext
    {
        public string Message = "";
        private readonly byte[] buffer = new byte[1024];
        public string RequestMethod;
        public string RequestUrl;
        public User RequestProfile;
        public User CurrentUser = null;
        public List<RequestValues> HeadersValues;
        public List<RequestValues> FormValues;
        private TcpClient TcpClient;

        private event Action<SslStream, RequestContext> OnRead = RequestHandler.OnHandle;

        DatabaseWorker databaseWorker = new DatabaseWorker();

        public RequestContext(SslStream ClientStream, TcpClient Client)
        {

            this.TcpClient = Client;
            try
            {
                ClientStream.BeginRead(buffer, 0, buffer.Length, ClientRead, ClientStream);
            }
            catch { return; }
        }
        private void ClientRead(IAsyncResult ar)
        {
            SslStream ClientStream = (SslStream)ar.AsyncState;

            if (ar.IsCompleted)
            {
                Message = Encoding.UTF8.GetString(buffer);
                Message = Uri.UnescapeDataString(Message);
                Console.WriteLine(

quot;n{DateTime.Now:g} Client IP:{TcpClient.Client.RemoteEndPoint}n{Message}");
RequestParse();
HeadersValues = HeaderValues();
FormValues = ContentValues();
UserParse();
ProfileParse();
OnRead?.Invoke(ClientStream, this);
}
}

private void RequestParse()
{
Match methodParse = Regex.Match(Message, @"(^w+)s+([^s?]+)[^s]*s+HTTP/.*|");
RequestMethod = methodParse.Groups[1].Value.Trim();
RequestUrl = methodParse.Groups[2].Value.Trim();
}
private void UserParse()
{
string cookie;
try
{
if (HeadersValues.Any(x => x.Name.Contains("Cookie")))
{
cookie = HeadersValues.FirstOrDefault(x => x.Name.Contains("Cookie")).Value;
try
{
CurrentUser = databaseWorker.CookieValidate(cookie);
}
catch { }
}
}
catch { }

}
private List<RequestValues> HeaderValues()
{
var values = new List<RequestValues>();
var parse = Regex.Matches(Message, @"(.*?): (.*?)n");
foreach (Match match in parse)
{
values.Add(new RequestValues()
{
Name = match.Groups[1].Value.Trim(),
Value = match.Groups[2].Value.Trim()
});
}
return values;
}

private void ProfileParse()
{
if (RequestUrl.Contains("@"))
{
RequestProfile = databaseWorker.FindUser(RequestUrl.Substring(2));
RequestUrl = "/profile";
}
}
private List<RequestValues> ContentValues()
{
var values = new List<RequestValues>();
var output = Message.Trim('n').Split().Last();
var parse = Regex.Matches(output, @"([^&].*?)=([^&]*b)");
foreach (Match match in parse)
{
values.Add(new RequestValues()
{
Name = match.Groups[1].Value.Trim(),
Value = match.Groups[2].Value.Trim().Replace('+', ' ')
});
}
return values;
}
}
}

Chofunikira chake ndi chakuti mothandizidwa ndi mawu okhazikika kuti athetse pempholo m'zigawo. Timalandira uthenga kuchokera kwa kasitomala, sankhani mzere woyamba, womwe uli ndi njira ndikupempha url. Kenaka timawerenga mitu, yomwe timayendetsa mumtundu wa HeaderName = Content, komanso kupeza, ngati zilipo, zomwe zikutsatiridwa (mwachitsanzo, querystring) zomwe timayendetsanso mofanana. Kuphatikiza apo, wofalitsayo amapeza ngati kasitomala wapano ali ndi chilolezo ndikusunga deta yake. Zopempha zonse zochokera kwamakasitomala ovomerezeka zimakhala ndi hashi yovomerezeka, yomwe imasungidwa mu makeke, chifukwa chake ndizotheka kulekanitsa malingaliro owonjezera amitundu iwiri yamakasitomala ndikuwapatsa mayankho olondola.

Chabwino, gawo laling'ono, labwino lomwe liyenera kusinthidwa kukhala gawo lina, kutembenuza zopempha ngati "site.com/@UserName" kukhala masamba opangidwa ndi ogwiritsa ntchito. Pambuyo pokonza zopemphazo, ma module otsatirawa amabwera.

Mutu 3. Kuyika chogwirizira, mafuta unyolo

Wophatikizayo akangomaliza, wogwirizira amalowa, akupereka malangizo ena kwa seva ndikugawa zowongolera m'magawo awiri.

chogwirizira chosavuta

using ClearServer.Core.UserController;
using System.Net.Security;
namespace ClearServer.Core.Requester
{
    public class RequestHandler
    {
        public static void OnHandle(SslStream ClientStream, RequestContext context)
        {

            if (context.CurrentUser != null)
            {
                new AuthUserController(ClientStream, context);
            }
            else 
            {
                new NonAuthUserController(ClientStream, context);
            };
        }
    }
}

M'malo mwake, pali cheke chimodzi chokha cha chilolezo cha ogwiritsa ntchito, pambuyo pake pempholi limayamba.

Owongolera Makasitomala
Ngati wogwiritsa ntchito saloledwa, ndiye kuti kwa iye ntchitoyo imangotengera mawonekedwe a ogwiritsa ntchito ndi zenera lolembetsa chilolezo. Khodi ya wogwiritsa ntchito wovomerezeka imawoneka chimodzimodzi, chifukwa chake sindikuwona chifukwa choyibwereza.

Wogwiritsa ntchito wosaloledwa

using ClearServer.Core.Requester;
using System.IO;
using System.Net.Security;

namespace ClearServer.Core.UserController
{
    internal class NonAuthUserController
    {
        private readonly SslStream ClientStream;
        private readonly RequestContext Context;
        private readonly WriteController WriteController;
        private readonly AuthorizationController AuthorizationController;

        private readonly string ViewPath = "C:/Users/drdre/source/repos/ClearServer/View";

        public NonAuthUserController(SslStream clientStream, RequestContext context)
        {
            this.ClientStream = clientStream;
            this.Context = context;
            this.WriteController = new WriteController(clientStream);
            this.AuthorizationController = new AuthorizationController(clientStream, context);
            ResourceLoad();
        }

        void ResourceLoad()
        {
            string[] blockextension = new string[] {"cshtml", "html", "htm"};
            bool block = false;
            foreach (var item in blockextension)
            {
                if (Context.RequestUrl.Contains(item))
                {
                    block = true;
                    break;
                }
            }
            string FilePath = "";
            string Header = "";
            var RazorController = new RazorController(Context, ClientStream);
            
            switch (Context.RequestMethod)
            {
                case "GET":
                    switch (Context.RequestUrl)
                    {
                        case "/":
                            FilePath = ViewPath + "/loginForm.html";
                            Header =

quot;HTTP/1.1 200 OKnContent-Type: text/html";
WriteController.DefaultWriter(Header, FilePath);
break;
case "/profile":
RazorController.ProfileLoader(ViewPath);
break;
default:
//Π² Π΄Π°Π½Π½ΠΎΠΌ Π±Π»ΠΎΠΊΠ΅ ΠΊΠΎΠ΄Π° происходит отсСчСниС запросов ΠΊ сСрвСру ΠΏΠΎ прямому адрСсу страницы Π²ΠΈΠ΄Π° site.com/page.html
if (!File.Exists(ViewPath + Context.RequestUrl) | block)
{
RazorController.ErrorLoader(404);

}
else if (Path.HasExtension(Context.RequestUrl) && File.Exists(ViewPath + Context.RequestUrl))
{
Header = WriteController.ContentType(Context.RequestUrl);
FilePath = ViewPath + Context.RequestUrl;
WriteController.DefaultWriter(Header, FilePath);
}
break;
}
break;

case "POST":
AuthorizationController.MethodRecognizer();
break;

}

}

}
}

Ndipo zowonadi, wogwiritsa ntchito ayenera kulandira zina zamasamba, kotero kuti mayankho pali gawo lotsatirali, lomwe limayang'anira kuyankha pempho lazinthu.

WriterController

using System;
using System.IO;
using System.Net.Security;
using System.Text;

namespace ClearServer.Core.UserController
{
    public class WriteController
    {
        SslStream ClientStream;
        public WriteController(SslStream ClientStream)
        {
            this.ClientStream = ClientStream;
        }

        public void DefaultWriter(string Header, string FilePath)
        {
            FileStream fileStream;
            try
            {
                fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                Header =

quot;{Header}nContent-Length: {fileStream.Length}nn";
ClientStream.Write(Encoding.UTF8.GetBytes(Header));
byte[] response = new byte[fileStream.Length];
fileStream.BeginRead(response, 0, response.Length, OnFileRead, response);
}
catch { }
}

public string ContentType(string Uri)
{
string extension = Path.GetExtension(Uri);
string Header = "HTTP/1.1 200 OKnContent-Type:";
switch (extension)
{
case ".html":
case ".htm":
return


quot;{Header} text/html";
case ".css":
return


quot;{Header} text/css";
case ".js":
return


quot;{Header} text/javascript";
case ".jpg":
case ".jpeg":
case ".png":
case ".gif":
return


quot;{Header} image/{extension}";
default:
if (extension.Length > 1)
{
return


quot;{Header} application/" + extension.Substring(1);
}
else
{
return


quot;{Header} application/unknown";
}
}
}

public void OnFileRead(IAsyncResult ar)
{
if (ar.IsCompleted)
{
var file = (byte[])ar.AsyncState;
ClientStream.BeginWrite(file, 0, file.Length, OnClientSend, null);
}
}

public void OnClientSend(IAsyncResult ar)
{
if (ar.IsCompleted)
{
ClientStream.Close();
}
}
}

Koma kuti ndiwonetse wogwiritsa ntchito mbiri yake ndi mbiri ya ogwiritsa ntchito ena, ndidaganiza zogwiritsa ntchito RazorEngine, kapena gawo lake. Zimaphatikizansopo kuthana ndi zopempha zoyipa ndikutulutsa code yolakwika yoyenera.

RazorController

using ClearServer.Core.Requester;
using RazorEngine;
using RazorEngine.Templating;
using System;
using System.IO;
using System.Net;
using System.Net.Security;

namespace ClearServer.Core.UserController
{
    internal class RazorController
    {
        private RequestContext Context;
        private SslStream ClientStream;
        dynamic PageContent;


        public RazorController(RequestContext context, SslStream clientStream)
        {
            this.Context = context;
            this.ClientStream = clientStream;

        }

        public void ProfileLoader(string ViewPath)
        {
            string Filepath = ViewPath + "/profile.cshtml";
            if (Context.RequestProfile != null)
            {
                if (Context.CurrentUser != null && Context.RequestProfile.login == Context.CurrentUser.login)
                {
                    try
                    {
                        PageContent = new { isAuth = true, Name = Context.CurrentUser.name, Login = Context.CurrentUser.login, Skills = Context.CurrentUser.skills };
                        ClientSend(Filepath, Context.CurrentUser.login);
                    }
                    catch (Exception e) { Console.WriteLine(e); }

                }
                else
                {
                    try
                    {
                        PageContent = new { isAuth = false, Name = Context.RequestProfile.name, Login = Context.RequestProfile.login, Skills = Context.RequestProfile.skills };
                        ClientSend(Filepath, "PublicProfile:"+ Context.RequestProfile.login);
                    }
                    catch (Exception e) { Console.WriteLine(e); }
                }
            }
            else
            {
                ErrorLoader(404);
            }


        }

        public void ErrorLoader(int Code)
        {
            try
            {
                PageContent = new { ErrorCode = Code, Message = ((HttpStatusCode)Code).ToString() };
                string ErrorPage = "C:/Users/drdre/source/repos/ClearServer/View/Errors/ErrorPage.cshtml";
                ClientSend(ErrorPage, Code.ToString());
            }
            catch { }

        }

        private void ClientSend(string FilePath, string Key)
        {
            var template = File.ReadAllText(FilePath);
            var result = Engine.Razor.RunCompile(template, Key, null, (object)PageContent);
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(result);
            ClientStream.BeginWrite(buffer, 0, buffer.Length, OnClientSend, ClientStream);
        }

        private void OnClientSend(IAsyncResult ar)
        {
            if (ar.IsCompleted)
            {
                ClientStream.Close();
            }
        }
    }
}

Ndipo zowona, kuti chitsimikiziro cha ogwiritsa ntchito ovomerezeka agwire ntchito, chilolezo chikufunika. Gawo lololeza limalumikizana ndi database. Zomwe zalandilidwa kuchokera ku mafomu omwe ali patsambali zimagawidwa kuchokera pazomwe zili patsamba, wogwiritsa ntchito amasungidwa ndikulandila ma cookie ndi mwayi wogwiritsa ntchito pobwezera.

Authorization module

using ClearServer.Core.Cookies;
using ClearServer.Core.Requester;
using ClearServer.Core.Security;
using System;
using System.Linq;
using System.Net.Security;
using System.Text;

namespace ClearServer.Core.UserController
{
    internal class AuthorizationController
    {
        private SslStream ClientStream;
        private RequestContext Context;
        private UserCookies cookies;
        private WriteController WriteController;
        DatabaseWorker DatabaseWorker;
        RazorController RazorController;
        PasswordHasher PasswordHasher;
        public AuthorizationController(SslStream clientStream, RequestContext context)
        {
            ClientStream = clientStream;
            Context = context;
            DatabaseWorker = new DatabaseWorker();
            WriteController = new WriteController(ClientStream);
            RazorController = new RazorController(context, clientStream);
            PasswordHasher = new PasswordHasher();
        }

        internal void MethodRecognizer()
        {
            if (Context.FormValues.Count == 2 && Context.FormValues.Any(x => x.Name == "password")) Authorize();
            else if (Context.FormValues.Count == 3 && Context.FormValues.Any(x => x.Name == "regPass")) Registration();
            else
            {
                RazorController.ErrorLoader(401);
            }
        }

        private void Authorize()
        {
            var values = Context.FormValues;
            var user = new User()
            {
                login = values[0].Value,
                password = PasswordHasher.PasswordHash(values[1].Value)
            };
            user = DatabaseWorker.UserAuth(user);
            if (user != null)
            {
                cookies = new UserCookies(user.login, user.password);
                user.cookie = cookies.AuthCookie;
                DatabaseWorker.UserUpdate(user);
                var response = Encoding.UTF8.GetBytes(

quot;HTTP/1.1 301 Moved PermanentlynLocation: /@{user.login}nSet-Cookie: {cookies.AuthCookie}; Expires={DateTime.Now.AddDays(2):R}; Secure; HttpOnlynn");
ClientStream.BeginWrite(response, 0, response.Length, WriteController.OnClientSend, null);

}
else
{
RazorController.ErrorLoader(401);

}
}

private void Registration()
{
var values = Context.FormValues;
var user = new User()
{
name = values[0].Value,
login = values[1].Value,
password = PasswordHasher.PasswordHash(values[2].Value),
};
cookies = new UserCookies(user.login, user.password);
user.cookie = cookies.AuthCookie;
if (DatabaseWorker.LoginValidate(user.login))
{
Console.WriteLine("User ready");
Console.WriteLine(


quot;{user.password} {user.password.Trim().Length}");
DatabaseWorker.UserRegister(user);
var response = Encoding.UTF8.GetBytes(


quot;HTTP/1.1 301 Moved PermanentlynLocation: /@{user.login}nSet-Cookie: {user.cookie}; Expires={DateTime.Now.AddDays(2):R}; Secure; HttpOnlynn");
ClientStream.BeginWrite(response, 0, response.Length, WriteController.OnClientSend, null);
}
else
{
RazorController.ErrorLoader(401);
}
}
}
}

Ndipo umu ndi momwe database imawonekera:

Nawonsomba

using ClearServer.Core.UserController;
using System;
using System.Data.Linq;
using System.Linq;

namespace ClearServer
{
    class DatabaseWorker
    {

        private readonly Table<User> users = null;
        private readonly DataContext DataBase = null;
        private const string connectionStr = @"ΠΏΡƒΡ‚ΡŒΠΊΠ±Π°Π·Π΅";

        public DatabaseWorker()
        {
            DataBase = new DataContext(connectionStr);
            users = DataBase.GetTable<User>();
        }

        public User UserAuth(User User)
        {
            try
            {
                var user = users.SingleOrDefault(t => t.login.ToLower() == User.login.ToLower() && t.password == User.password);
                if (user != null)
                    return user;
                else
                    return null;
            }
            catch (Exception)
            {
                return null;
            }

        }

        public void UserRegister(User user)
        {
            try
            {
                users.InsertOnSubmit(user);
                DataBase.SubmitChanges();
                Console.WriteLine(

quot;User{user.name} with id {user.uid} added");
foreach (var item in users)
{
Console.WriteLine(item.login + "n");
}
}
catch (Exception e)
{
Console.WriteLine(e);
}

}

public bool LoginValidate(string login)
{
if (users.Any(x => x.login.ToLower() == login.ToLower()))
{
Console.WriteLine("Login already exists");
return false;
}
return true;
}
public void UserUpdate(User user)
{
var UserToUpdate = users.FirstOrDefault(x => x.uid == user.uid);
UserToUpdate = user;
DataBase.SubmitChanges();
Console.WriteLine(


quot;User {UserToUpdate.name} with id {UserToUpdate.uid} updated");
foreach (var item in users)
{
Console.WriteLine(item.login + "n");
}
}
public User CookieValidate(string CookieInput)
{
User user = null;
try
{
user = users.SingleOrDefault(x => x.cookie == CookieInput);
}
catch
{
return null;
}
if (user != null) return user;
else return null;
}
public User FindUser(string login)
{
User user = null;
try
{
user = users.Single(x => x.login.ToLower() == login.ToLower());
if (user != null)
{
return user;
}
else
{
return null;
}
}
catch (Exception)
{
return null;
}
}
}
}


Ndipo chirichonse chimagwira ntchito ngati clockwork, chilolezo ndi ntchito yolembetsa, ntchito yochepa yopezera ntchitoyo ilipo kale ndipo ndi nthawi yolemba ntchito ndikumangiriza chinthu chonsecho ndi ntchito zazikulu zomwe zonse zimachitidwa.

Mutu 4

Kuchepetsa ndalama zogwirira ntchito polemba mapulogalamu awiri a nsanja ziwiri, ndinaganiza zopanga mtanda pa Xamarin.Mafomu. Apanso, chifukwa chakuti ili mu C #. Nditapanga mayeso omwe amangotumiza deta ku seva, ndidakumana ndi mphindi imodzi yosangalatsa. Pa pempho kuchokera ku chipangizochi, kuti ndisangalale, ndinachigwiritsa ntchito pa HttpClient ndikuchiponyera pa seva HttpRequestMessage yomwe ili ndi deta kuchokera ku fomu yovomerezeka mu mtundu wa json. Popanda kuyembekezera chirichonse makamaka, ndinatsegula chipika cha seva ndikuwona pempho kuchokera ku chipangizocho ndi deta yonse kumeneko. Kuwala pang'ono, kuzindikira zonse zomwe zachitika m'masabata atatu apitawa amadzulo. Kuti muwone kulondola kwazomwe zatumizidwa, ndinasonkhanitsa seva yoyesera pa HttpListner. Nditalandira pempho lotsatira kale, ndidazipatula mumizere ingapo, ndidapeza data ya KeyValuePair kuchokera pafomu. Kukambirana kwa mafunso kwachepetsedwa kukhala mizere iwiri.

Ndinayamba kuyesanso, sizinatchulidwe kale, koma pa seva yapitayi ndidakhazikitsabe macheza opangidwa pa websockets. Zinagwira ntchito bwino, koma mfundo yolumikizirana kudzera pa Tcp inali yokhumudwitsa, zowonjezera zambiri zidayenera kupangidwa kuti apange kulumikizana kwabwino kwa ogwiritsa ntchito awiri ndikulemba makalata. Izi zikuphatikizapo kufotokoza pempho la kusintha kwa kugwirizana ndi kusonkhanitsa yankho pogwiritsa ntchito protocol ya RFC 6455. Choncho, mu seva yoyesera, ndinaganiza zopanga kugwirizana kosavuta kwa websocket. Chifukwa cha chidwi.

Kulumikizana ndi macheza

 private static async void HandleWebsocket(HttpListenerContext context)
        {
            var socketContext = await context.AcceptWebSocketAsync(null);
            var socket = socketContext.WebSocket;
            Locker.EnterWriteLock();
            try
            {
                Clients.Add(socket);
            }
            finally
            {
                Locker.ExitWriteLock();
            }

            while (true)
            {
                var buffer = new ArraySegment<byte>(new byte[1024]);
                var result = await socket.ReceiveAsync(buffer, CancellationToken.None);
                var str = Encoding.Default.GetString(buffer);
                Console.WriteLine(str);

                for (int i = 0; i < Clients.Count; i++)
                {
                    WebSocket client = Clients[i];

                    try
                    {
                        if (client.State == WebSocketState.Open)
                        {
                            
                            await client.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        Locker.EnterWriteLock();
                        try
                        {
                            Clients.Remove(client);
                            i--;
                        }
                        finally
                        {
                            Locker.ExitWriteLock();
                        }
                    }
                }
            }
        }

Ndipo zinathandiza. Seva yokhayo idakhazikitsa kulumikizana, idapanga kiyi yoyankha. Sindinayeneranso kukhazikitsa padera kulembetsa kwa seva kudzera pa ssl, ndizokwanira kuti dongosololi lili ndi satifiketi yoyikidwa padoko lofunikira.

Kumbali ya chipangizo ndi pa tsamba, makasitomala awiri adasinthanitsa mauthenga, zonsezi zidalowetsedwa. Palibe magawo akulu omwe akuchedwetsa seva, palibe chomwe chidafunikira. Nthawi yoyankha yachepetsedwa kuchokera ku 200ms mpaka 40-30ms. Ndipo ndinafika pa chisankho chokhacho choyenera.

Kupalasa njinga kwapamwamba kapena pulogalamu ya kasitomala-seva kutengera C# .Net framework

Tayani kukhazikitsa kwa seva komweko pa Tcp ndikulembanso zonse pansi pa Http. Tsopano polojekitiyi ili pa siteji yokonzanso, koma molingana ndi mfundo zosiyana kwambiri za mgwirizano. Kugwiritsa ntchito zida ndi tsambalo zimalumikizidwa ndikusinthidwa ndipo zimakhala ndi lingaliro lofanana, ndi kusiyana kokha komwe zida sizifunikira kupanga masamba a html.

Pomaliza

"Popanda kudziwa ford, usalowetse mutu wako m'madzi" Ndikuganiza kuti, ndisanayambe ntchito, ndiyenera kufotokozera momveka bwino zolinga ndi zolinga, komanso ndikufufuza zaumisiri wofunikira ndi njira zogwiritsira ntchito makasitomala osiyanasiyana. Ntchitoyi yatsala pang'ono kutha, koma mwina ndibweranso kuti tidzakambirane m'mene ndinasokonezanso zinthu zina. Ndinaphunzira zambiri panthawi ya chitukuko, koma pali zambiri zoti ndiphunzire m'tsogolomu. Ngati mwawerenga mpaka pano, ndiye zikomo powerenga.

Source: www.habr.com