UDP 這樣的無鏈接協議中,並無持久化鏈接這樣的概念,而且每一個消息(一個UDP 數據報)都是一個單獨的傳輸單元。此外,UDP 也沒有TCP 的糾錯機制。html
經過類比,TCP 鏈接就像打電話,其中一系列的有序消息將會在兩個方向上流動。相反,UDP 則相似於往郵箱中投入一疊明信片。你沒法知道它們將以何種順序到達它們的目的地,或者它們是否全部的都可以到達它們的目的地。算法
UDP的這些方面可能會讓你感受到嚴重的侷限性,可是它們也解釋了爲什麼它會比TCP快那麼多:全部的握手以及消息管理機制的開銷都已經被消除了。顯然,UDP很適合那些可以處理或者容忍消息丟失的應用程序,但可能不適合那些處理金融交易的應用程序。後端
自己做爲無鏈接的不可靠的傳輸協議(適合頻繁發送較小的數據包),他不會對數據包進行合併發送(也就沒有Nagle算法之說了),他直接是一端發送什麼數據,直接就發出去了,既然他不會對數據合併,每個數據包都是完整的(數據+UDP頭+IP頭等等發一次數據封裝一次)也就沒有粘包一說了。瀏覽器
單播的傳輸模式,定義爲發送消息給一個由惟一的地址所標識的單一的網絡目的地。面向鏈接的協議和無鏈接協議都支持這種模式。服務器
廣播——傳輸到網絡(或者子網)上的全部主機。網絡
interface AddressedEnvelope<M, A extends SocketAddress>extends ReferenceCounted併發
定義一個消息,其包裝了另外一個消息並帶有發送者和接收者地址。其中M 是消息類型;A 是mvc
地址類型框架
class DefaultAddressedEnvelope<M, A extends SocketAddress>implements AddressedEnvelope<M,A>提供了interface AddressedEnvelope的默認實現異步
class DatagramPacket extends DefaultAddressedEnvelope<ByteBuf, InetSocketAddress> implements ByteBufHolder
擴展了DefaultAddressedEnvelope 以使用ByteBuf 做爲消息數據容器。DatagramPacket是final類不能被繼承,只能被使用。
經過content()來獲取消息內容
經過sender();來獲取發送者的消息
經過recipient();來獲取接收者的消息。
interface DatagramChannel extends Channel
擴展了Netty 的Channel 抽象以支持UDP 的多播組管理
class NioDatagramChannnel extends AbstractNioMessageChannel implements DatagramChannel
定義了一個可以發送和接收Addressed-Envelope 消息的Channel 類型
Netty 的DatagramPacket 是一個簡單的消息容器,DatagramChannel 實現用它來和遠程節點通訊。相似於在咱們先前的類比中的明信片,它包含了接收者(和可選的發送者)的地址以及消息的有效負載自己。
參見模塊udp下的包cn.enjoyedu.udp.unicast
參見模塊udp下的包cn.enjoyedu.udp.broadcast
服務器推送技術幹嗎用?就是讓用戶在使用網絡應用的時候,不須要一遍又一遍的去手動刷新就能夠及時得到更新的信息。你們平時在上各類視頻網站時,對視頻節目進行歡樂的吐槽和評論,會看到各類彈幕,固然,他們是用flash技術實現的,對於咱們沒有用flash的應用,同樣能夠實現彈幕。又好比在股票網站,每每能夠看到,各類股票信息的實時刷新,上面的這些都是基於服務器推送技術。
具體代碼參見模塊comet
就是用一個定時器不停的去網站上請求數據。
「服務器推」是一種很早就存在的技術,之前在實現上主要是經過客戶端的套接口,或是服務器端的遠程調用。由於瀏覽器技術的發展比較緩慢,沒有爲「服務器推」的實現提供很好的支持,在純瀏覽器的應用中很難有一個完善的方案去實現「服務器推」並用於商業程序。,由於 AJAX 技術的普及,gmail等等在實現中使用了這些新技術;同時「服務器推」在現實應用中確實存在不少需求。稱這種基於 HTTP長鏈接、無須在瀏覽器端安裝插件的「服務器推」技術爲「Comet」。
Spring mvc的控制層接收用戶的請求以後,若是要採用異步處理,那麼就要返回DeferedResult<>泛型對象。在調用完控制層以後,當即回返回DeferedResult對象,此時驅動控制層的容器主線程,能夠處理更多的請求。
能夠將DeferedResult對象做爲真實響應數據的代理,而真實的數據是該對象的成員變量result,它能夠是String類型,或者ModelAndView類型等。
業務處理完畢以後,要執行setResult方法,將真實的響應數據賦值到DeferedResult對象中。此時,容器主線程會繼續執行getResult方法,將真實數據響應到客戶端。
嚴格地說,HTTP 協議沒法作到服務器主動推送信息。可是,有一種變通方法,就是服務器向客戶端聲明,接下來要發送的是流信息(streaming)。
也就是說,發送的不是一次性的數據包,而是一個數據流,會接二連三地發送過來。這時,客戶端不會關閉鏈接,會一直等着服務器發過來的新的數據流,視頻播放就是這樣的例子。本質上,這種通訊就是以流信息的方式,完成一次用時很長的下載。
SSE 就是利用這種機制,使用流信息向瀏覽器推送信息。它基於 HTTP 協議,目前除了 IE/Edge,其餘瀏覽器都支持。
SSE 與 WebSocket 做用類似,都是創建瀏覽器與服務器之間的通訊渠道,而後服務器向瀏覽器推送信息。
整體來講,WebSocket 更強大和靈活。由於它是全雙工通道,能夠雙向通訊;SSE 是單向通道,只能服務器向瀏覽器發送,由於流信息本質上就是下載。若是瀏覽器向服務器發送信息,就變成了另外一次 HTTP 請求。
SSE 也有本身的優勢。
SSE 使用 HTTP 協議,現有的服務器軟件都支持。WebSocket 是一個獨立協議。
SSE 屬於輕量級,使用簡單;WebSocket 協議相對複雜。
SSE 默認支持斷線重連,WebSocket 須要本身實現。
SSE 通常只用來傳送文本,二進制數據須要編碼後傳送,WebSocket 默認支持傳送二進制數據。
SSE 支持自定義發送的消息類型。
服務器向瀏覽器發送的 SSE 數據,必須是 UTF-8 編碼的文本,具備以下的 HTTP 頭信息。
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
上面三行之中,第一行的Content-Type必須指定 MIME 類型爲event-steam。
每一次發送的信息,由若干個message組成,每一個message之間用\n\n分隔。每一個message內部由若干行組成,每一行都是以下格式。
[field]: value\n
上面的field能夠取四個值。
data
event
id
retry
此外,還能夠有冒號開頭的行,表示註釋。一般,服務器每隔一段時間就會向瀏覽器發送一個註釋,保持鏈接不中斷。例子 : this is a test stream\n\n
數據內容用data字段表示。
data: message\n\n
若是數據很長,能夠分紅多行,最後一行用\n\n結尾,前面行都用\n結尾。
data: begin message\n
data: continue message\n\n
下面是一個發送 JSON 數據的例子。
data: {\n
data: "foo": "bar",\n
data: "baz", 555\n
data: }\n\n
數據標識符用id字段表示,至關於每一條數據的編號。
id: msg1\n
data: message\n\n
瀏覽器用lastEventId屬性讀取這個值。一旦鏈接斷線,瀏覽器會發送一個 HTTP 頭,裏面包含一個特殊的Last-Event-ID頭信息,將這個值發送回來,用來幫助服務器端重建鏈接。所以,這個頭信息能夠被視爲一種同步機制。
event字段表示自定義的事件類型,默認是message事件。瀏覽器能夠用addEventListener()監聽該事件。
event: foo\n
data: a foo event\n\n
data: an unnamed event\n\n
event: bar\n
data: a bar event\n\n
上面的代碼創造了三條信息。第一條的名字是foo,觸發瀏覽器的foo事件;第二條未取名,表示默認類型,觸發瀏覽器的message事件;第三條是bar,觸發瀏覽器的bar事件。
服務器能夠用retry字段,指定瀏覽器從新發起鏈接的時間間隔。
retry: 10000\n
兩種狀況會致使瀏覽器從新發起鏈接:一種是時間間隔到期,二是因爲網絡錯誤等緣由,致使鏈接出錯。
京東用的什麼?Ajax短輪詢,這說明什麼?這些技術並無什麼優劣之分,只有合不合適業務的問題。京東的痛點是什麼?要用有限的資源來爲千萬級甚至上億的用戶提供服務,若是是用長鏈接,對於接入的服務器,好比說Nginx,是很大的壓力,光是爲用戶維持這個長鏈接都須要成百上千的Nginx的服務器,這是很划不來的。由於對於京東這類購物網站來講,用戶的瀏覽查詢量是遠遠大於用戶下單量的,京東須要注重的是服務更多的用戶,並且相對於用戶瀏覽頁面的圖片等等的流量而言,這點帶寬浪費佔比是很小的。因此咱們看京東的付款後的實現,是用的短輪詢機制,並且時長放大到了5秒。
SSE和WebSocket相比的優點。最大的優點就是便利:不須要添加任何新組件,用任何你習慣的後端語言和框架就能繼續使用。你不用爲新建虛擬機、弄一個新的IP或新的端口號而勞神,就像在現有網站中新增一個頁面那樣簡單。能夠稱爲既存基礎設施優點。
SSE的第二個優點是服務端的簡潔。相對而言,WebSocket則很複雜,不借助輔助類庫基本搞不定。WebSocket能作的,SSE也能作,反之亦然,但在完成某些任務方面,它們各有千秋。WebSocket是一種更爲複雜的服務端實現技術,但它是真正的雙向傳輸技術,既能從服務端向客戶端推送數據,也能從客戶端向服務端推送數據。