成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

websocket筆記以及一個微型聊天室例子

heartFollower / 858人閱讀

摘要:收到包后,向發(fā)送一個值為,該包發(fā)送完成后,和均進(jìn)入狀態(tài)。非強(qiáng)制壓縮發(fā)送。因此也就誕生了一個新的通信協(xié)議協(xié)議,一種全雙工通信協(xié)議。會發(fā)起一個握手的請求,請求首部含有還有其他首部,具體看如下示例。服務(wù)器端返回一個狀態(tài)碼,確認(rèn)轉(zhuǎn)換協(xié)議。

首先說明:這里的tomcat用的是tomcat8.0.36,并不適合tomcat7以及以下版本,(沒辦法websocket的api一直在變,到8之后貌似穩(wěn)定下來了)

websocket也是html5的新增加內(nèi)容之一,號稱是下一代客戶端/服務(wù)器異步通信辦法,私以為雖然有點吹牛的成分,但是以后說不定能成為異步通信的半壁江山,至于取代ajax,我覺的應(yīng)該不會

websocket的一個很有意思的特點就是雙向通信,這一點其實也不稀奇,跟socket一樣的。
我記得大二上學(xué)期的java課程設(shè)計我做的是一個仿照QQ的用戶程序socket通信,寫起來雖然順暢但是因為那個c/s架構(gòu)寫起來痛苦不已,只實現(xiàn)一個簡單的群聊就要大概一千五的代碼量,尤其回調(diào)函數(shù)跟界面綁定的時候,寫起來很X痛,從此就再沒寫過windows界面程序
下邊是websocket的原理性知識總結(jié)是寫給我自己看的,如果你沒興趣,可以跳過直接到代碼:

tcp建立連接
tcp連接的建立需要經(jīng)歷”三次握手“的過程。過程如下client發(fā)送SYN包(值為j)以及SEQ包到server端,此時client進(jìn)入SYN_SEND狀態(tài)。此為第一次握手。server端收到SYN包后,發(fā)送一個ACK(值為seq+1)確認(rèn)包和SYN(值為k)給client,此時server進(jìn)入SYN_RECV狀態(tài)。此為第二次握手。client收到SYN+ACK包后,向server發(fā)送一個ACK(值為k+1),該包發(fā)送完成后,client和server均進(jìn)入ESTABLISH狀態(tài)。此為第三次握手。

client和server兩端狀態(tài)變化如下:

client:

CLOSED->SYN_SEND->ESTABLISH

server:

CLOSED->LISTEN->SYN_RECV->ESTABLISH

tcp連接釋放
Tcp釋放連接的過程需要經(jīng)歷“四次揮手”的過程,為什么建立連接只需要3次握手,而釋放連接需要進(jìn)行4次揮手呢?很簡單,因為TCP連接是全雙工(Full Duplex)的,因此造成了兩個方向都需要進(jìn)行關(guān)閉。怎么理解呢?client和server,需要關(guān)閉連接,此時client通知server我要關(guān)閉連接了,此時關(guān)閉的只會是client這一端的連接,而server端并未關(guān)閉,它依舊能夠向client發(fā)送數(shù)據(jù)。當(dāng)然,關(guān)閉連接也可以是server作為主動方的。接下來以client主動斷開與server端的連接為場景來描述整個過程,我們把它分為兩個階段,分別為client端關(guān)閉連接和server端關(guān)閉連接。

第一階段

首先client會發(fā)送一個FIN包給server(同時還有ack和seq包),這是要告訴server,我已經(jīng)沒有數(shù)據(jù)要發(fā)給你了,此時client處于FIN_WAIT_1狀態(tài)。接收到FIN包的server處于CLOSE_WAIT的狀態(tài)。
server發(fā)回一個ACK(值為client傳過來的seq+1)和seq(值為client傳過來的ack的值)給client。client收到server發(fā)過來的包后確認(rèn)關(guān)閉連接,此時client處于FIN_WAIT_2。

第二階段

server在接收到client的FIN后,得知client要斷開tcp連接了,于是在發(fā)送完ack和seq給client后,自己發(fā)送一個FIN包給client(也帶有ack和seq包),告訴client我也要斷開連接了,此時server處于LAST_ACK狀態(tài)。
client接收到server的FIN信息后,會回復(fù)server一個ack包,并且會進(jìn)入TIME_WAIT狀態(tài),持續(xù)2個MSL(Max Segment Lifetime),這個時間windows下為240s。而server接收到client后便關(guān)閉連接。client在指定時間過后仍然沒有接收到server的數(shù)據(jù),確認(rèn)server已經(jīng)沒有數(shù)據(jù)過來,也關(guān)閉了連接。
此時雙方都進(jìn)入CLOSED狀態(tài)。

建立細(xì)節(jié)

tcp是傳輸層的協(xié)議,tcp三次握手后,應(yīng)用層協(xié)議http也便建立了連接。而對于當(dāng)今web的發(fā)展情況,http仍有許多瓶頸。

一條連接只能發(fā)送一個請求。
請求只能從客戶端開始。客戶端不可以接收除響應(yīng)以外的指令。
請求/響應(yīng)首部未經(jīng)壓縮發(fā)送,首部信息越多延遲越大。
發(fā)送冗長的首部。每次互相發(fā)送相同的首部造成較多的浪費。
可任意選擇數(shù)據(jù)壓縮格式。非強(qiáng)制壓縮發(fā)送。
雖然已經(jīng)出現(xiàn)了很多解決方案,如ajax、comet,但是他們最終使用的都是http協(xié)議,因此也無法從根本上解決這些瓶頸。

因此也就誕生了一個新的通信協(xié)議,WebSocket協(xié)議,一種全雙工通信協(xié)議。

該通信協(xié)議建立在http協(xié)議的基礎(chǔ)之上,因此連接的發(fā)起方仍然是客戶端,在http連接建立之后,再將協(xié)議升級為webSocket連接,在webSocket連接建立之后,客戶度和服務(wù)器端都可以主動向?qū)Ψ桨l(fā)送報文信息了。

建立webSocket連接,需要先建立http連接,并在此基礎(chǔ)上再進(jìn)行一次”握手“。

client會發(fā)起一個”握手“的請求,請求首部含有upgrade:websocket(還有其他首部,具體看如下示例)。服務(wù)器端返回一個101狀態(tài)碼,確認(rèn)轉(zhuǎn)換協(xié)議。完成握手后便可以使用websocket協(xié)議進(jìn)行通信。

Client(request)

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: AQIDBAUGBwgJCgsMDQ4PEC==
Origin: http://example.com
Sec-WebSocket-protocol: chat, superchat
Sec-WebSocket-Version: 13

server (response)

HTTP/1.1 101 switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat

websocket這個協(xié)議涉及前端顯示,以及服務(wù)器處理,我這里使用基礎(chǔ)的java+js來實現(xiàn)一個簡單的群聊

如果不熟悉websocket的api,你可以看這里:https://developer.mozilla.org...
以及:https://www.ibm.com/developer...

重要的只有兩個文件:chat.java以及chat.html

Chat.java:

package example;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;


@ServerEndpoint(value="/ws/chat/{nickName}")
public class Chat {
    private static final Set connections = new CopyOnWriteArraySet();
    private String nickName;
    private Session session;
    
    
    public Chat(){
        
    }
    
    /*
     * 打開連接
     */    
    @OnOpen
    public void onOpen(Session session,@PathParam(value="nickName") String nickName){
        this.session=session;
        this.nickName=nickName;
        connections.add(this);
        System.out.println("新用戶連接進(jìn)入,名字是:"+this.nickName);
        String message=String.format("System>%s %s",this.nickName,"hasjoined.");
        Chat.broadCast(message);
        
    }
    /*
     * 關(guān)閉連接
     */
    @OnClose
    public void onClose(){
        connections.remove(this);
        String message=String.format("System> %s, %s", this.nickName,
                " has disconnection.");
        Chat.broadCast(message);
    }
    
    /*
     * 接收信息
     */
    @OnMessage
    public void onMessage(String message,@PathParam(value="nickName")String nickName){
        System.out.println("新消息from:"+nickName+" : "+message);
        Chat.broadCast(nickName+">"+message);
    }
    /*
     * 錯誤消息
     */
    @OnError
    public void onError(Throwable throwable){
        System.out.println(throwable.getMessage());
    }
    /*
     * 廣播消息
     */
    private static void broadCast(String message){
        for(Chat chat:connections){
            try{
                synchronized (chat) {
                    chat.session.getBasicRemote().sendText(message);
                }
            }catch(IOException e){
                connections.remove(chat);
                try{
                    chat.session.close();
                    
                }catch(IOException e1){
                    chat.broadCast(String.format("System> %s %s", chat.nickName,
                            " has bean disconnection."));
                }
            }
        }
    }
}

chat.html:





Testing websockets


  

一些問題:
WebSockets 簡介:將套接字引入網(wǎng)絡(luò)

WebSocket 是什么原理?為什么可以實現(xiàn)持久連接?(看尤雨溪大神的回答)

再談應(yīng)用環(huán)境下的TIME_WAIT和CLOSE_WAIT

如果你熟悉nodejs你還可以:
使用Node.js+Socket.IO搭建WebSocket實時應(yīng)用

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91000.html

相關(guān)文章

  • websocket筆記以及一個微型天室例子

    摘要:收到包后,向發(fā)送一個值為,該包發(fā)送完成后,和均進(jìn)入狀態(tài)。非強(qiáng)制壓縮發(fā)送。因此也就誕生了一個新的通信協(xié)議協(xié)議,一種全雙工通信協(xié)議。會發(fā)起一個握手的請求,請求首部含有還有其他首部,具體看如下示例。服務(wù)器端返回一個狀態(tài)碼,確認(rèn)轉(zhuǎn)換協(xié)議。 首先說明:這里的tomcat用的是tomcat8.0.36,并不適合tomcat7以及以下版本,(沒辦法websocket的api一直在變,到8之后貌似穩(wěn)定...

    zzbo 評論0 收藏0
  • Websocket解析及實現(xiàn)

    摘要:早期的輪詢是通過不斷自動刷新頁面而實現(xiàn)的。長輪詢的另一個問題是缺乏標(biāo)準(zhǔn)實現(xiàn)。服務(wù)器端接到這個請求后作出回應(yīng)并不斷更新連接狀態(tài)以保證客戶端和服務(wù)器端的連接不過期。協(xié)議解析協(xié)議包含兩部分一部分是握手,一部分是數(shù)據(jù)傳輸。 Websocket是什么? Websocket是一個因為應(yīng)用場景越來越復(fù)雜而提出的,針對瀏覽器和web服務(wù)器之間雙向持續(xù)通信而設(shè)計,而且優(yōu)雅地兼容HTTP的協(xié)議(我猜想:同...

    XboxYan 評論0 收藏0
  • 學(xué)習(xí)實踐 - 收藏集 - 掘金

    摘要:官網(wǎng)地址聊天機(jī)器人插件開發(fā)實例教程一創(chuàng)建插件在系統(tǒng)技巧使你的更加專業(yè)前端掘金一個幫你提升技巧的收藏集。我會簡單基于的簡潔視頻播放器組件前端掘金使用和實現(xiàn)購物車場景前端掘金本文是上篇文章的序章,一直想有機(jī)會再次實踐下。 2道面試題:輸入URL按回車&HTTP2 - 掘金通過幾輪面試,我發(fā)現(xiàn)真正那種問答的技術(shù)面,寫一堆項目真不如去刷技術(shù)文章作用大,因此刷了一段時間的博客和掘金,整理下曾經(jīng)被...

    mikyou 評論0 收藏0

發(fā)表評論

0條評論

heartFollower

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<