Netty tutvustus (Net on DotNetty)

Introduction Netty



(Esmalt kurdame Microsofti üle väga palju) , vihkan rauda, ​​mitte terast. Kuid hiljutise Net Core'i väljaandmise tõttu tõmbas see aeglaselt tagasi väikese osa maailmast, mis kuulub Microsoftile, ning peatus ja vestles.

DotNetty on kujundatud Azure'i meeskonna (peaaegu nii) JAVA Netty (praegu Netty osa) järgi ja praegusel Githubi Staril on 1,8K + aadressil https://github.com/Azure/DotNetty. Dokumendid puuduvad ja koodis on vähe kommentaare. Kuigi see on Netty'ist juba aastaid väljas olnud, peaksid meie NET-i programmeerijad olema tänulikud, et nad saavad lõpuks oma platvormil kasutada sellist võimsat suhtlusraamistikku nagu Netty.



Traditsioonilise suhtluse probleem:

Me kasutame omavahel suhtlemiseks tavalisi rakendusi või klasside raamatukogusid. Näiteks kasutame sageli veebiserverist teabe hankimiseks või veebiteenuse kaudu kaugkõne tegemiseks HTTP-klientide teeki.



Kuid mõnikord ei vasta üldine protokoll või selle rakendamine vajadustele hästi. Näiteks ei saa me kasutada ühist HTTP-serverit suurte failide, meilide ja peaaegu reaalajas toimuvate sõnumite, näiteks finantsteabe ja mitme mängijaga andmete käitlemiseks. Mõne eristsenaariumi käsitlemiseks vajame kõrgelt optimeeritud protokolli. Näiteks võiksite rakendada optimeeritud Ajaxi vestlusrakenduse, meedia voogesituse või suure failiedastuse ning oma vajaduste täpseks elluviimiseks võite isegi kujundada ja rakendada täiesti uue protokolli.



Teine vältimatu olukord on see, kui peate pärandsüsteemidega koostalitlusvõime tagamiseks tegelema pärandvaraga varustatud protokollidega. Sel juhul on oluline, kuidas saame protokolli kiiresti rakendada, ohverdamata rakenduse stabiilsust ja jõudlust.

lahendama:

Netty on võrgurakenduste raamistik, mis pakub asünkroonseid sündmustepõhiseid (asünkroonseid sündmustepõhiseid), servereid ja kliente suure jõudlusega, skaleeritavate protokollide kiireks arendamiseks.

Teisisõnu, Netty on NIO kliendiserveri raamistik, mis võimaldab teil kiiresti ja hõlpsalt arendada veebirakendusi, näiteks serveri ja kliendi protokolle. Netty lihtsustab oluliselt võrguprogrammide nagu TCP ja UDP sokliteenuste väljatöötamist.



„Kiire ja lihtne” ei tähenda, et rakendustel oleks probleeme raske hoolduse ja madala jõudlusega. Netty on hästi läbimõeldud raamistik, mis ammutab palju kogemusi paljudest protokollide juurutamistest nagu FTP, SMTP, HTTP ja paljud binaarsed. Ja traditsioonilised tekstipõhised protokollid. Seetõttu on Nettyil õnnestunud leida viis, kuidas saavutada arendamise lihtsus, kõrge jõudlus ja stabiilsus ilma paindlikkust kaotamata.

Mõni kasutaja võib olla avastanud, et ka teistel võrguraamistikel on samad eelised, nii et võite küsida Netty ja nende erinevuste kohta. Vastus on Netty filosoofia kujundusfilosoofia. Algusest peale on Netty pakkunud kasutajatele parima kasutuskogemuse API ja rakenduse kujunduse. Just Netty filosoofilise disainifilosoofia tõttu saate seda juhendit hõlpsasti lugeda ja Netty'i kasutada.

640? Wx_fmt = jpeg

(DotNetty raamistik ja juurutamine käib, ma ei tea palju, kuid DotNetty-ga seotud API-liideste õppimiseks ja kasutamiseks võin viidata Netty ametlikule dokumentatsioonile.)

DotNetty'is on mitu olulist raamatukogu (assambleed):

DotNetty.Buffers: mälupuhvri halduse kapseldamine.

DotNetty.Codecs: koodek on kapseldatud, sealhulgas mõned aluseks oleva baasklassi rakendused, ja projektis kohandatud protokollid pärivad konkreetse baasklassi ja projekti rakendamise.

DotNetty.Codecs.Mqtt: MQTT (Message Queue Telemetry Transport) koodek on kapseldatud ja sisaldab mõnda alusbaasi rakendust.

DotNetty.Codecs.Protobuf: Protobufi koodek on kapseldatud ja sisaldab mõningaid aluseks olevate baasklasside rakendusi.

DotNetty.Codecs.ProtocolBuffers: ProtocolBuffersi koodek on kapseldatud ja sisaldab mõningaid alusklassi rakendusi.

DotNetty.Codecs.Redis: Redise protokolli koodek on kapseldatud ja sisaldab mõningaid aluseks olevate baasklasside rakendusi.

DotNetty. Common

DotNetty.Handlers: ümbritseb tavalisi torujuhtme protsessoreid, näiteks Tls-koodekeid, ajalõppemehhanisme, südamelöögikontrolli, logisid ja palju muud.

DotNetty.Transport: DotNetty põhitegevus, sokli infrastruktuur, suhtlusrežiim: asünkroonne mitteblokeerimine.

DotNetty.Transport.Libuv: DotNetty rakendab oma põhirakendust, mis põhineb Libuvil (suure jõudlusega, sündmustepõhine sisend- ja väljundraamatukogu).

Tavaliselt kasutatavad teegid on kodekid, tavaline, käitlejad, puhvrid, transport. Praegu rakendab Azure'i meeskond Netty'is muid API-sid (sealhulgas mitteavalikke Netty API-sid). Jääme ootama ja vaatama.

Kastanid suhtlevad otse eakaaslaste vahel

DotNetty kausta Näide abil on palju ametlikke näiteid, nagu näiteks Visake ära teenuse eksemplar (viskamine), vastusteenuse eksemplar (kaja), Telneti teenuse eksemplar jne. Otsese peer-to-peer suhtluse saavutamiseks kasutasin Echo demot. RPC kõne rakendatakse ka Echo põhjal, kommenteerides üksikasjalikult otse vastuvõtja (serveri) koodi:

/ *

* Netty on poolfabrikaat, mis täidab oma suhtluspaketti kohandatud protokolli põhjal.

* Netty lihtsustab oluliselt võrguprogrammide nagu TCP ja UDP sokliteenuste väljatöötamist.

* 'Kiire ja lihtne' ei tähenda, et rakendusel oleks probleeme raske hoolduse ja madala jõudlusega.

* Netty on hästi läbimõeldud raamistik, mis ammutab palju kogemusi paljudest protokollide juurutamistest nagu FTP, SMTP, HTTP, paljud binaarsed ja traditsioonilised tekstipõhised protokollid.

* Seetõttu on Netty edukalt leidnud viisi, kuidas saavutada arendamise lihtsus, kõrge jõudlus ja stabiilsus paindlikkust kahjustamata.

* /

nimeruum Kaja. Server

{

kasutades süsteemi

kasutades System.Threading.Tasks

kasutades DotNetty.Koodekeid

kasutades DotNetty.Handlers.Logging

kasutades DotNetty.Transport.Bootstrapping

kasutades DotNetty.Transport.Channels

kasutades DotNetty.Transport.Libuv

kasutades näiteid.Sage

staatiline klass Programm

{

staatiline asünkroonimine Ülesanne RunServerAsync ()

{

ExampleHelper.SetConsoleLogger ()

// Kuulutame peatsükli ajastamise rühma

var dispetšer = new DispatcherEventLoopGroup ()

/ *

Netty pakub EventLoopGroupi palju erinevaid rakendusi, et hallata erinevaid ülekandeid.

Selles näites juurutasime serveripoolse rakenduse, seega tuleb kasutada 2 NioEventLoopGroupsi.

Esimest nimetatakse sissetulevate ühenduste saamiseks sageli ülemuseks. Teist nimetatakse sageli töötajaks, mis tegeleb juba saadud ühendustega. Kui ülemus on ühenduse saanud, registreerib ta ühenduse teabe töötajaga.

Kuidas teada saada, mitu lõime on kasutatud, kuidas juba loodud kanalile kaardistada, sõltub IEventLoopGroupi juurutamisest ja saate nende suhte konfigureerida konstruktori kaudu.

* /

// peamine töötaja lõimerühm, määrake 1 lõim

IEventLoopGroup bossGroup = dispetšer // (1)

// lapstöötaja lõimerühm, määrake 1 lõng

IEventLoopGroup workerGroup = uus WorkerEventLoopGroup (dispetšer)

proovige

{

// Kuulutage serveri alglaadimisseade, iga Netty serveriprogrammi juhib ServerBootstrap ja vajalikud parameetrid pannakse kokku aheldatud viisil.

var serverBootstrap = uus ServerBootstrap () // (2)

// Määra põhi- ja töövõtte lõimegrupid

serverBootstrap.Group (bossGroup, workerGroup)

if (ServerSettings.UseLibuv)

{

// Deklareerige, et serveri sidekanal on TcpServerChannel

serverBootstrap.Channel () // (3)

}

serverBootstrap

/ / Määra võrgu IO parameetrid jne.

.Option (ChannelOption.SoBacklog, 100) // (5)

// Määrake protsessor logi printimiseks keermete põhirühma

.Käitleja (uus LoggingHandler ('SRV-LSTN'))

/ / Töötaja lõime parameetrite määramine

.ChildHandler (

/ *

* ChannelInitializer on spetsiaalne töötlusklass, mille eesmärk on aidata kasutajatel uut kanalit konfigureerida.

* Võib-olla soovite rakendada võrguprogrammi, lisades uue kanali või sellele vastava ChannelPipeline'i konfigureerimiseks mõne töötlusklassi, näiteks DiscardServerHandler.

* Kui teie programm muutub keerukamaks, võite lisada torujuhtmele rohkem töötlusklasse ja seejärel need anonüümsed klassid ülemisse klassi välja tõmmata.

* /

uus ActionChannelInitializer (// (4)

kanal =>

{

/ *

* Töötaja niidi pistik on seadistatud toruga ja kogu serveri peaniidi saadud teave edastatakse torukihi kaudu alla.

* Samal ajal töötlevad kõiki selle hüpikprotsessi töötlejaid samm-sammult ka kõiki hüpikaknaid.

* /

IChannelPipeline pipeline = kanal. Torujuhe

/ / Lisage logi pealtkuulaja

pipeline.AddLast (uus LoggingHandler ('SRV-CONN'))

// Lisage hüpikaken ja lisage selle käitleja kaudu sõnumi pikkus sõnumi ülaossa.

// LengthFieldPrepender (2): andmete pikkuse salvestamiseks kasutage 2 baiti.

pipeline.AddLast ('framing-enc', uus LengthFieldPrepender (2))

/ *

Tõukesõnum edastab käitleja, sõelub teate paketipikkuse teabe ja saadab järgmise sõnumi töötlejale õige sõnumi keha.

1, InitialBytesToStrip = 0, / / ​​lugemisel vahelejäetavate baitide arv

2, LengthAdjustment = -5, / / ​​pakendi tegeliku pikkuse korrigeerimine, kui paketi pikkus sisaldab päist ja keha, lahutage seejärel pikkuse eelne osa

3, LengthFieldLength = 4, / / ​​pikkuse välja Integer baitide arv on 4 baiti

4, LengthFieldOffset = 1, / / ​​alguse (nihke) bitt atribuudi pikkus

5, MaxFrameLength = int.MaxValue, / / ​​paketi maksimaalne pikkus

* /

pipeline.AddLast ('raamimine-dets', uus LengthFieldBasedFrameDecoder (ushort.MaxValue, 0, 2, 0, 2))

// ärikorraldaja

pipeline.AddLast ('echo', uus EchoServerHandler ())

}))

// Bootstrapi seostamine määratud pordiga on see, et server käivitab teenuse ja sama Serverbootstrap saab siduda mitme pordiga.

ICkanal boundChannel = ootab serverBootstrap.BindAsync (ServerSettings.Port) // (6)

Console.WriteLine ('oodake kliendi sisendit')

Console.ReadLine ()

// teenuse sulgemine

ootama bindChannel.CloseAsync ()

}

lõpuks

{

// vabastage määratud töörühma lõim

ootama Task.WhenAll (// (7)

bossGroup.ShutdownGracatelyAsync (TimeSpan.FromMilliseconds (100), TimeSpan.FromSeconds (1)),

workerGroup.ShutdownGracatelyAsync (TimeSpan.FromMilliseconds (100), TimeSpan.FromSeconds (1))

)

}

}

staatiline void Main () => RunServerAsync (). Oota ()

}

}

  1. IEventLoopGroup on mitmekeermeline sündmuste ringlusring I / O toimingute haldamiseks. DotNetty pakub EventLoopGroupi palju erinevaid rakendusi, et hallata erinevaid ülekandeid. Selles näites juurutasime serveripoolse rakenduse, seega tuleb kasutada kahte IEventLoopGroupsi. Esimest nimetatakse sissetulevate ühenduste saamiseks sageli ülemuseks. Teist nimetatakse sageli töötajaks, mis tegeleb juba saadud ühendustega. Kui ülemus on ühenduse saanud, registreerib ta ühenduse teabe töötajaga.

  2. ServerBootstrap on sekundaarne käivitamisklass, mis käivitab transporditeenuse. Kanalit saate selles teenuses kasutada otse, kuid see võib olla keeruline protsess ja paljudel juhtudel pole teil seda vaja teha.

  3. Siinkohal täpsustame klassi TcpServerChannel kasutamist, et illustreerida, kuidas uus kanal saabuvaid ühendusi vastu võtab.

  4. ChannelInitializer on spetsiaalne töötlemisklass. Selle eesmärk on aidata kasutajatel uut kanalit konfigureerida. Kui teie programm muutub keerulisemaks, võite lisada pipline'ile rohkem töötlusklasse ja seejärel neid anonüümseid klasse kõige rohkem ekstraheerida. Klassi tipptasemel.

  5. Siin saate määrata kanali rakenduse konfiguratsiooniparameetrid. Kirjutame TCP / IP-serverit, seega on meil lubatud määrata sokli parameetrite valikud, näiteks tcpNoDelay ja keepAlive.

  6. Siduge sadam ja alustage teenust. Siin seome masina võrgukaardil määratud pordi masinaga. Muidugi võite meetodit bind () kutsuda mitu korda (erinevate sidumisaadresside põhjal).

  7. Pärast kasutamist vabastage määratud töörühma lõime elegantselt, muidugi võite programmi sulgeda, kuid see pole soovitatav.

Serveripoolne sündmuste käitlemise kood:

Paksu koha rakendamine koodi eelmises osas

nimeruum Kaja. Server

{

kasutades süsteemi

kasutades süsteemi.Text

kasutades DotNetty.Buffersit

kasutades DotNetty.Transport.Channels

///

/// Server haldab sündmuste funktsioone

///

Avaliku klassi EchoServerHandler: ChannelHandlerAdapter // ChannelHandlerAdapteri ettevõte pärib baasklassi adapteri // (1)

{

///

/// Torujuhe hakkab lugema

///

///

///

avalik tühistamine void ChannelRead (IChannelHandlerContext kontekst, objektisõnum) // (2)

{

if (sõnum on IByteBufferi puhver) // (3)

{

Console.WriteLine ('Kliendilt saadud:' + puhver. ToString (Encoding.UTF8))

}

context.WriteAsync (sõnum) // (4)

}

///

/// Torujuhtme lugemine on lõpule viidud

///

///

public override void ChannelReadComplete (IChannelHandlerContext context) => context.Flush () // (5)

///

/// Ebanormaalne

///

///

///

avalik tühistamine tühine ExceptionCaught (IChannelHandlerContext kontekst, erandi erand)

{

Console.WriteLine ('Erand:' + erand)

kontekst.CloseAsync ()

}

}

}

  1. DiscardServerHandler pärib kanalilt ChannelInboundHandlerAdapter. See klass rakendab IChannelHandleri liidest. IChannelHandler pakub sündmuste käitlemiseks mitmeid liidese meetodeid ja seejärel saate need meetodid tühistada. Nüüd peate lihtsalt laiendama klassi ChannelInboundHandlerAdapter, selle asemel, et ise liidese meetodeid rakendada.

  2. Siin alistame sündmuse käitleja chanelRead (). Kui kliendilt saadakse uusi andmeid, kutsutakse seda meetodit sõnumi saabumisel. Selles näites on vastuvõetud sõnumi tüüp ByteBuf.

  3. Kliendi saadetud teabele vastamiseks või kuvamiseks printime kliendilt andmed konsoolis välja.

  4. Seejärel kirjutame kliendi sõnumi konteksti kaudu kliendile tagasi. WriteAsync.

  5. Muidugi, 4. samm lihtsalt salvestab voo konteksti ja ei tee tegelikku kirjutamistoimingut. Flush kirjutab loputusandmed torujuhtmele ja edastatakse konteksti kaudu sissetulevale kliendile.

Kliendipoolne kood:

Keskenduge kommentaaride kohale, teiste kohtade ja serveripoole vahel pole vahet.

nimeruum Kaja. Klient

{

kasutades süsteemi

kasutades System.Net

kasutades süsteemi.Text

kasutades System.Threading.Tasks

kasutades DotNetty.Buffersit

kasutades DotNetty.Koodekeid

kasutades DotNetty.Handlers.Logging

kasutades DotNetty.Transport.Bootstrapping

kasutades DotNetty.Transport.Channels

kasutades DotNetty.Transport.Channels.Sockets

kasutades näiteid.Sage

staatiline klass Programm

{

staatiline asünkroonimine Ülesanne RunClientAsync ()

{

ExampleHelper.SetConsoleLogger ()

var group = uus MultithreadEventLoopGroup ()

proovige

{

var bootstrap = uus alglaadur ()

bootstrap

. Grupp (rühm)

.Kanal ()

.Option (ChannelOption.TcpNodelay, true)

. Kaupleja (

uus ActionChannelInitializer (

kanal =>

{

IChannelPipeline pipeline = kanal. Torujuhe

pipeline.AddLast (uus LoggingHandler ())

pipeline.AddLast ('framing-enc', uus LengthFieldPrepender (2))

pipeline.AddLast ('raamimine-dets', uus LengthFieldBasedFrameDecoder (ushort.MaxValue, 0, 2, 0, 2))

pipeline.AddLast ('echo', uus EchoClientHandler ())

}))

ICkanali klientChannel = ootab alglaadimist. ConnectAsync (uus IPEndPoint (ClientSettings.Host, ClientSettings.Port))

// Loo lõpmatu silmus, mis on sarnane While (true)

jaoks () // (4)

{

Console.WriteLine ('sisestage andmed:')

// Looge seadete põhjal puhvri suurus

IByteBuffer initialMessage = Ühendamata. Puhver (ClientSettings.Size) // (1)

string r = Console.ReadLine ()

/ / Kirjutage andmevoog puhvrisse

initialMessage.WriteBytes (Encoding.UTF8.GetBytes (r ?? viska uus InvalidOperationException ())) // (2)

// Puhvervoo kirjutamine torujuhtmele

ootama clientChannel.WriteAndFlushAsync (initialMessage) // (3)

kui (r. Sisaldab ('bye'))

murda

}

Console.WriteLine ('byebye')

ootama clientChannel.CloseAsync ()

}

lõpuks

{

ootama gruppi.ShutdownGracatelyAsync (TimeSpan.FromMilliseconds (100), TimeSpan.FromSeconds (1))

}

}

staatiline void Main () => RunClientAsync (). Oota ()

}

}

  1. Algata puhvri suurus.

  2. Vaikepuhver aktsepteerib baitide andmetüüpe [], mis muidugi hõlbustab voogudeks järjestamist.

  3. Kirjutage voo otseandmed puhvrist kanali torujuhtmele. See toru on tavaliselt lingiühenduse teine ​​ots (C-ots).

  4. On loodud lõpmatu silmus. Selle eesmärk on testida andmeid, mis tuleb kliendilt sisestada iga kord, pärast seda, kui serverisilmus on üks, ja seejärel järgmist sisestustoimingut.

Kliendipoolne sündmuste käitlemise kood:

nimeruum Kaja. Klient

{

kasutades süsteemi

kasutades süsteemi.Text

kasutades DotNetty.Buffersit

kasutades DotNetty.Transport.Channels

avalik klass EchoClientHandler: ChannelHandlerAdapter

{

kirjutuskaitstud IByteBuffer initialMessage

avalik tühistamine void ChannelActive (IChannelHandlerContext context) => context.WriteAndFlushAsync (this.initialMessage)

avalik tühistamine tühine ChannelRead (kontekst IChannelHandlerContext, objektisõnum)

{

if (sõnum on IByteBuffer byteBuffer)

{

Console.WriteLine ('Saadud serverist:' + byteBuffer.ToString (Encoding.UTF8))

}

}

avalik tühistamine void ChannelReadComplete (IChannelHandlerContext context) => context.Flush ()

avalik tühistamine tühine ExceptionCaught (IChannelHandlerContext kontekst, erandi erand)

{

Console.WriteLine ('Erand:' + erand)

kontekst.CloseAsync ()

}

}

}

Väga lihtne, andmevoo kuvamine konsoolile.

Rakendamise tulemus

Siinkohal kasutame lihtsa vastusserveri loomiseks DotNetty raamistikku. See on väga lihtne, mõju on järgmine:

Pärast seda, kui C-ots aktiivselt andmeid S-otsa saadab, võtab S-ots need vastu, prindib andmed konsoolile ja saadab need tagasi C-otsa. Muidugi saab S-pool teha palju asju.

640? Wx_fmt = png

DotNetty sisemine silumisrekordide analüüs

Kuigi DotNetty ei esita tehnilist dokumentatsiooni, esitab ametnik üksikasjalikud silumisdokumendid. Paljudel juhtudel saavad meie õppijad dokumentide silumisega analüüsida ka teatud funktsiooni rakendamise protsessi. Saame DotNetty sisemised sisend- ja väljundkirjed konsooli printida.

InternalLoggerFactory.DefaultFactory.AddProvider(new ConsoleLoggerProvider((s, level) => true, false))

Näete, et serveri poolel on palju rohkem prindikirjeid, millest enamik on DotNetty sisemise silumise prindikirjed. Keskendume ainult järgmistele jaotistele.

dbug: SRV-LSTN [0]

[id: 0x3e8afca1] HANDLER_ADDED

dbug: SRV-LSTN [0]

[id: 0x3e8afca1] REGISTREERITUD (1)

dbug: SRV-LSTN [0]

[id: 0x3e8afca1] BIND: 0.0.0.0:8007 (2)

oota kliendi sisendit

dbug: SRV-LSTN [0]

[id: 0x3e8afca1, 0.0.0.0:8007] AKTIIVNE (3)

dbug: SRV-LSTN [0]

[id: 0x3e8afca1, 0.0.0.0:8007] LOE (4)

dbug: SRV-LSTN [0]

[id: 0x3e8afca1, 0.0.0.0:8007] SAATUD: [id: 0x7bac2775, 127.0.0.1:64073:> 127.0.0.1:8007] (5)

dbug: SRV-LSTN [0]

[id: 0x3e8afca1, 0.0.0.0:8007] RECEIVED_COMPLETE (6)

dbug: SRV-LSTN [0]

[id: 0x3e8afca1, 0.0.0.0:8007] LOE (7)

dbug: SRV-CONN [0]

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] HANDLER_ADDED (8)

dbug: SRV-CONN [0]

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] REGISTREERITUD (9)

dbug: SRV-CONN [0]

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] AKTIIVNE (10)

dbug: SRV-CONN [0]

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] LOE (11)

dbug: DotNetty.Buffers.AbstractByteBuffer [0] (12)

-Dio.netty.buffer.bytebuf.checkAccessible: tõsi

dbug: SRV-CONN [0]

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] SAATUD: 14B, 13)

+ ------------------------------------------------- +

| 0 1 2 3 4 5 6 7 8 9 a b c d e f |

+ -------- + ---------------------------------------- --------- + ---------------- +

| 100000000 | 00 0C 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 | .. tere maailm! |

+ -------- + ---------------------------------------- --------- + ---------------- +

Saadud kliendilt: tere maailm!

dbug: SRV-CONN [0] (14)

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] KIRJUTA: 2B

+ ------------------------------------------------- +

| 0 1 2 3 4 5 6 7 8 9 a b c d e f |

+ -------- + ---------------------------------------- --------- + ---------------- +

| 100000000 | 00 0C | .. |

+ -------- + ---------------------------------------- --------- + ---------------- +

dbug: SRV-CONN [0] (15)

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] KIRJUTA: 12B

+ ------------------------------------------------- +

| 0 1 2 3 4 5 6 7 8 9 a b c d e f |

+ -------- + ---------------------------------------- --------- + ---------------- +

| 100000000 | 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 | tere maailm! |

+ -------- + ---------------------------------------- --------- + ---------------- +

dbug: SRV-CONN [0] (16)

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] RECEIVED_COMPLETE

dbug: SRV-CONN [0] (17)

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] FLUSH

dbug: SRV-CONN [0] (18)

[id: 0x7bac2775, 127.0.0.1:64073 => 127.0.0.1:8007] LOE

Esmapilgul on 18 toimingut, mis näivad olevat natuke liiga palju. Tegelikult on palju sisemisi silumisdetaile, mida konsoolile ei trükita.

  1. Kui loote käsitsi töölisekomplekti ja registreerite lõimekomplekti torujuhtmesse, võib see torujuhe põhineda SOCKERil ja IChannelil (1)

  2. Seostage kohandatud IP-aadress ja pordi number kohandatud toruga (2)

  3. Aktiveerige kohandatud torujuhe (3)

  4. Alustage lugemist (hakake tegelikult ka kuulama) (4)

  5. Sai ID-lt 0x7bac2775 kliendiühendustaotluse, lõi ühenduse ja hakkas kuulama (5) (6) (7)

  6. Alates 8. etapist on logist saanud rekord id-ga 0x7bac2775, muidugi, sealhulgas registreerimistorustik, aktiveerimistorustik, seire algus jne. Sama operatsioon nagu S-terminalil (8) (9) (10) (11)

  7. Kui autor siseneb 'tere maailma!' andmed, DotNetty.Buffers.AbstractByteBuffer kontrollib andmetüübi kinnitamist, et andmeid saaks torujuhtmesse panna. (12)

  8. Saatke andmed S-otsa, andmete suurus on 14B, tere maailma ees on kaks punkti, mis tähendab, et see on andmete päis, ja saatke siis veel kaks punkti, kuid andmeid pole, see tähendab, et andmed on lõppenud. DotNetty väljendab andmete kuueteistkümnendsüsteemis salvestusbitte kergesti arusaadaval viisil ja on väga kasutajasõbralik. (13) (14)

  9. S-ots võtab andmed vastu ilma töötlemise ja töötlemiseta ning tagastab andmed viivitamatult C-otsa. (15) (16)

  10. Lõpuks, kui see protsess on lõpule jõudnud, tuleb puhverala andmed gaasijuhtmesse sundida, nii et tehakse loputusoperatsioon ja kogu ülekanne on lõpule viidud. Järgmisena, olgu see siis C-poolne või S-poolne, jätkake oleku muutmist READ-ks, mida kasutatakse torujuhtme erinevate olukordade jälgimiseks, näiteks ühenduse olek, andmeedastus jne (17).

Kokkuvõtteks

Sõpradele, kes on pistikprogrammide kasutamisel uued, on see õudusunenägu, sest sokli programmeerimise keerukus pole nii lihtne ega keeruline kui mitmikeermeline. Protokollid, pakkimine, transportimine, mitmelõimimine, nuhkimine, voo juhtimine jne on mitmete probleemide ees, seega on Netty hea avatud lähtekoodiga raamistik, kuid Netty on poolfabrikaat, kuna peate rakendama oma tema põhjal tahan. , teisaldamine ja muud kohandatud toimingud ning nende aluseks olev sisu, ei huvita teid üldse. Erinevalt mõnest raamistikust, näiteks Newtonsoft.Json, saab funktsionaalset raamistikku, konfiguratsiooni ega kohandamist otse kasutada.

Kuigi DotNetty on aidanud meil rakendada paljusid operatsioone allosas, kui te pole sellega kursis või ei mõista võrgusuhtlust üldse, kehtib sama ka ülaltoodud koodi kohta. Miks? Turuvajadused, meie programmeerijad tormavad iga päev äri juurde, kuidas ma saan rohkem teada saada ja rohkem teada saada ... Silumisdokumentide printimisega ja ükshaaval analüüsimisega hakkan tasapisi kõige paremini aru saama. Lihtne suhtlusprotsess.

See artikkel rakendab ainult lihtsamat suhtlusprotsessi, mis põhineb DotNetty'il, teeb lihtsalt andmete tsükli ega tee RPC-ga seotud kõnesid. Järgmine hakkab sellest näitest rääkima ja tutvustab RPC kõnet DotNetty põhjal.

Algne aadress: https://www.cnblogs.com/SteveLee/p/9860507.html

Kordustrükk: https://www.cnblogs.com/lhxsoft/p/10783073.html