本文原版本為官方英文文檔,詳情見官方http://tokio.rs
Amultiplexedsocket connection is one that allows many concurrent requests to be issued, with responses coming back in the order they are ready, rather than in the order requested. Multiplexing allows a server to begin processing requests as soon as they are received and to respond to the client as soon as the request is processed. Generally, multiplexed protocols will make better usage of available resources like TCP sockets.
多路復用socket鏈接允許同時并發(fā)多個請求,按照處理完成順序響應(yīng),而不是按照請求順序響應(yīng)。多路利用允許一個服務(wù)只要請求一到達就開始處理這些請求,同時只要請求一處理完成應(yīng)當響應(yīng)。一般來說,多路復用協(xié)議更好的利用了像TCP socket資源。
Since responses arrive out of order, arequest IDis used to match responses with their associated requests. When the client issues a request, the request will be paired with an identifier. The server processes the request, and sends a response to the client paired with the same request identifier. This allows the client to match the response with the request that it issued.
因為響應(yīng)到是無序的,所以使用request ID來匹配request和他的響應(yīng)。當client發(fā)起一個請求時,這個請求和一個標識組合。這服務(wù)處理這個請求,發(fā)現(xiàn)響應(yīng)的時候帶上相同的請求標識。客戶端就能匹配到發(fā)起請求的響應(yīng)結(jié)果。
Flow of multiplexed requests and responses
多路復用請求和響應(yīng)流程圖
Tokio makes implementing multiplexed clients and servers easy. This guide will show how.
Tokio使多路復用client和server實現(xiàn)變得更加簡單。具體見下面介紹:
Just as with theecho serverguide, implementing a client or server for a multiplexed protocol is done in three parts:
實現(xiàn)一個client和server多路復用分為三個步驟:
Atransport, which manages serialization of Rust request and response types to the underlying socket. In this guide, we will implement this using theframedhelper, just as before.
Transport,負責將Rust 請求和響應(yīng)類型序列化到低層socket.這里,我們將使用framer helper實現(xiàn)
Aprotocol specification, which puts together a codec and some basic information about the protocol.
Protocol規(guī)范,將編碼器與一些協(xié)議基本信息組合到一起。
Aservice, which says how to produce a response given a request. A service is basically an asynchronous function.
Service,負責處理請求的響應(yīng)邏輯。一個service一般是一個異步function。
Each part can vary independently, so once you’ve implemented a protocol (like HTTP), you can pair it with a number of different services.
每一部分都是獨立的,你一旦實現(xiàn)了一個協(xié)議(像http),你可以與其它的服務(wù)組合。
This guide specifically covers implementing asimplemultiplexed protocol. Thenext sectionwill show how to implement a streaming protocol.
本文包含實現(xiàn)一個簡單的多路復用協(xié)議。下一章展示如何實現(xiàn)一個stream協(xié)議。
The full implementation can be found in thetokio-linerepository. Let’s take it step by step.
Step 1: Implement a transport?
實現(xiàn)一個transport
In Tokio, atransportis any type implementingStream+Sinkwhere the yielded items are frames.
在Tokio,一個Transport 是一個實現(xiàn)了Stream+Sink?trait的類型,其生產(chǎn)的items都是frames
同樣,我們將實現(xiàn)line-based協(xié)議,不過這次是全雙工,是由frames組成的stream,每一個frame包含:
? ? ? ? ? ? 1、在網(wǎng)絡(luò)字節(jié)序中,頭4字節(jié)表示request ID。
? ? ? ? ? ? ?2、Frame payload,一個UTF-8編碼的不定長的字符串,以字符"\n"結(jié)束
注意,這些Line不支持包含轉(zhuǎn)義后的換行符。
使用tokio-proto全雙工后,我們的transport會變得復雜,frame將是由request Id和payload組件的元組構(gòu)成的。
use tokio_proto::multiplex::RequestId;
type MyMultiplexedFrame = (RequestId, T);
TheT here represents the request or response type used for theService.tokio-protowill use theRequestIdin the frame to match outstanding requests with responses.
T 代表的是請求或響應(yīng)的類型。tokio-ptoto將使用request id去匹配請求和響應(yīng)。
Step 2:?實現(xiàn)Protocol
下一步是定義協(xié)議細節(jié)。
Step 3:實現(xiàn)服務(wù)
An interesting thing to note is thatRequestIddoes not show up as part of theService’s request and response types. TheRequestIdis only needed for tokio-proto to manage the internal state of keeping requests and responses matched when operating on the transport.
一個比較有意思的事情是Request ID 并沒有作為Service的Request和Response類型的一部分,Request Id只是被tokio-proto用來在transport上管理內(nèi)部狀態(tài)和匹配request和response。
Again, you can find the full working example?here.