分類基礎:java
1,moba:multiplayer online Battle Arena.多人在線戰術競技遊戲;web
例子:王者榮耀編程
2,FPS:first person shooting game,第一人稱視角射擊遊戲數組
例子:全軍出擊;服務器
3,RPG:Role-playing Game:角色扮演遊戲;網絡
webSocket編程:併發
解決痛點:全雙工通訊,服務端主動推送,消耗資源少異步
網絡同步異步:jvm
同步:用戶進程觸發io操做並等待或者輪詢地去查看io操做是否就緒。socket
異步:用戶進程觸發io操做之後就能夠去處理其它操做,當io操做已經完成的時候會獲得io完成的通知。
阻塞和非阻塞是進程在訪問數據的時候,io操做是否被掛起。
阻塞式io:每個客戶端接入,服務器都要創建一個新的線程來進行處理(不開也能夠,單線程處理,性能會很低就是),客戶端鏈接數和服務端鏈接數以1:1方式呈現。因此,當客戶端鏈接數增多,產生高併發的時候,整個bio網絡程序將佔用大量的jvm線程,服務器性能降低,線程數達到必定數量後,jvm拋出堆棧異常,形成宕機。
非阻塞式io:
高併發io特色
1,建立一個線程負責處理io事件和io事件的分發;
2,事件驅動機制非同步監視事件,而是事件到達以後觸發。
3,線程之間經過wai,notify等方式通訊,減小沒必要要的線程切換。
服務器實現模式:一個處理全部請求的webwocket線程;根據處理類型分到read,write,disconnect等對應線程去,減小線程切換開銷。
緩衝器RecvBuffer:全部請求過來的數據,先丟到一個緩衝器buffer中,這個buffer實質是個字節數組ByteBuffer,若是RecvBuffer有對應的數據,則馬上返回數據,若是沒有,直接返回0,等到有數據的時候,直接返回,永遠不會阻塞。
在nio中 socket的主要讀寫註冊和接收函數,在等待就緒階段都是非阻塞的,真正的I/O操做時同步阻塞的。
tcp主要事件:讀就緒,寫就緒,有新的鏈接來。咱們首先須要註冊當這幾個事件到來的時候所對應的處理器。而後在合適的時機告訴事件選擇器:我對這個事件感興趣。對於寫操做,就是寫不出去的時候對寫事件感興趣;對於讀操做,就是完成鏈接和系統沒有辦法承載新讀入的數據的時;對於accept,通常是服務器剛啓動的時候;而對於connect,通常是connect失敗須要重連或者直接異步調用connect的時候。
其次,用一個死循環選擇就緒的事件,會執行系統調用(Linux 2.6以前是select、poll,2.6以後是epoll,Windows是IOCP),還會阻塞的等待新事件的到來。新事件到來的時候,會在selector上註冊標記位,標示可讀、可寫或者有鏈接到來。
注意,select是阻塞的,不管是經過操做系統的通知(epoll)仍是不停的輪詢(select,poll),這個函數是阻塞的。因此你能夠放心大膽地在一個while(true)裏面調用這個函數而不用擔憂CPU空轉。
因此咱們的程序大概的模樣是:
interface ChannelHandler{ void channelReadable(Channel channel); void channelWritable(Channel channel); } class Channel{ Socket socket; Event event;//讀,寫或者鏈接 } //IO線程主循環: class IoThread extends Thread{ public void run(){ Channel channel; while(channel=Selector.select()){//選擇就緒的事件和對應的鏈接 if(channel.event==accept){ registerNewChannelHandler(channel);//若是是新鏈接,則註冊一個新的讀寫處理器 } if(channel.event==write){ getChannelHandler(channel).channelWritable(channel);//若是能夠寫,則執行寫事件 } if(channel.event==read){ getChannelHandler(channel).channelReadable(channel);//若是能夠讀,則執行讀事件 } } } Map<Channel,ChannelHandler> handlerMap;//全部channel的對應事件處理器 }