国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

基于Server-SentEvent的簡單在線聊天室

2019-11-14 17:27:20
字體:
來源:轉載
供稿:網友

Web即時通信

所謂Web即時通信,就是說我們可以通過一種機制在網頁上立即通知用戶一件事情的發生,是不需要用戶刷新網頁的。Web即時通信的用途有很多,比如實時聊天,即時推送等。如當我們在登陸瀏覽 知乎時如果有人回答了我們的問題,知乎就會即時提醒我們,再比如現在電子商務的在線客服功能。這些能大大提高用戶體驗的功能都是基于Web即時通信實現的。

  • 普通HTTP流程
    1. 客戶端從服務器端請求網頁
    2. 服務器作出相應的反應
    3. 服務器返回相應到客戶端

而由于HTTP請求是無狀態的,也就是說每次請求完成后,HTTP鏈接就斷開了,服務器和瀏覽器互相之間是完全不可知的,只有下一次再發起一次請求 才能更新相應的信息。談到這里我們就不難想到,我們可以簡單的讓瀏覽器每隔一個周期就發起一次請求,這樣就能在一定程度上模擬實時效果了,這也就是輪訓,術語叫做Polling。

  • Polling流程
    1. 客戶端使用普通的http方式向服務器端請求網頁
    2. 客戶端執行網頁中的javaScript輪詢腳本,定期循環的向服務器發送請求(例如每5秒發送一次請求),獲取信息
    3. 服務器對每次請求作出響應,并返回相應信息,就像正常的http請求一樣

通過輪訓的方式我們就可以相對即時的獲取信息。但是由于輪訓的原理是使瀏覽器頻繁的向服務器發起請求,這在一定程度上會造成性能效率問題。為了優化 這些性能問題,人們又想到了一種方法。那就是在服務器接收到請求的時候不理解返回,而是只有當有數據變化(或者超時)的時候才返回。這樣一來,我們就可以 利用一次請求最大可能的保持連接的有效性,大大的減少了Polling中的請求次數。這個方法叫做長輪訓,也叫做Long-Polling。

以上方法是實現Web實時通信的常用方法。當然在HTML5出來之后,我們就有更好的選擇啦。在HTML5中,我們可以使用SSE或者是WebSocket。SSE的全稱是Server Send Event,聽名字就很好理解啦。也就是由服務器來推送數據。看到這里是不是興奮呢?其實很多情況下,我們只需要這種簡單的功能:由服務器推送數據到瀏覽器。比如推送比賽信息、股價的變化等等。

如果SSE還不能滿足我們的需求的話,我們完全就可以使用WebSocket啦。當使用WebSocket時,瀏覽器和服務器之間就建立了一個全雙工通道,互相都可以發送消息,完全的做到了及時,就像使用tcp socket一樣。

  • SSE和WebSocket的簡單對比:
    • WebSocket是全雙工通道,可以雙向通信,功能更強;SSE是單向通道,只能服務器向瀏覽器端發送。
    • WebSocket是一個新的協議,需要服務器端支持;SSE則是部署在HTTP協議之上的,現有服務器軟件都支持。
    • SSE是一個輕量級協議,相對簡單;WebSocket是一種較重的協議,相對復雜。

到這里我們就基本了解了一些事先Web實時通信的機制,下一節中,我們將使用SSE實現一個簡單的在線聊天室。

基于SSE的在線聊天室的實現

在線聊天室推送消息有很多種方式,在這門課程中我們使用SSE來實現。為了方便接收消息,我們借助Redispub/sub功能來接收和發送消息。Web服務器端我們將使用Flask實現。如果對Flask不是很熟悉,也可以在實驗樓學習相關的Flask課程。(http://www.shiyanlou.com/)

1. SSE 的工作方式

在上面的課程中,我們了解到SSE是基于HTTP實現的,那么瀏覽器怎么樣知道這是一個服務器事件流呢?其實很簡單啦,就是將HTTP的頭部Content-Type設置成text/event-stream就可以了。其實SSE,就是瀏覽器向服務器發送一個HTTP請求,然后服務器不斷單向地向瀏覽器推送"信息",這些信息的格式也非常簡單,就是前綴data:加上發送的數據內容,然后以/n/n結尾。

2. Redis中的訂閱功能

Redis是很流行的一個內存數據庫,可以用于實現緩存,隊列等服務。在這門項目課程中我們將使用的Redis的發布/訂閱功 能。簡單來說,我們所謂訂閱功能就是我們可以訂閱一些頻道,然后當這些頻道有新的消息的時候我們就可以自動接收這些信息。當服務器接收到瀏覽器POST過 來的消息的時候,會將這些信息發布到特定的頻道中。接著我們之前訂閱了這些頻道的客戶端就回自動收到這些消息,最后我們就將這些消息通過SSE推送到客戶端。

3. 實現

經過上面的分析,整個聊天室的流程已經很清晰啦。下面通過源代碼注釋的方式進行分析吧。在/home/shiyanlou目錄下,創建目錄code,然后在該目錄下創建源文件app.py

# 消息生成器def event_stream():    pubsub = r.pubsub()    # 訂閱'chat'頻道    pubsub.subscribe('chat')    # 開始監聽消息,如果有消息產生在返回消息    for message in pubsub.listen():        PRint message        # Server-Send Event的數據格式以'data:'開始        yield 'data: %s/n/n' % message['data']# 登陸函數,首次訪問需要登陸@app.route('/login', methods=['GET', 'POST'])def login():    if flask.request.method == 'POST':        # 將用戶信息記錄到session        flask.session['user'] = flask.request.form['user']        return flask.redirect('/')    return '<form action="" method="post">user: <input name="user">'# 接收Javascript post過來的消息@app.route('/post', methods=['POST'])def post():    message = flask.request.form['message']    user = flask.session.get('user', 'anonymous')    now = datetime.datetime.now().replace(microsecond=0).time()    # 將消息發布到'chat'頻道中    r.publish('chat', u'[%s] %s: %s' % (now.isoformat(), user, message))return flask.Response(status=204)

 

 

詳細代碼請登錄實驗樓http://www.shiyanlou.com/courses/?course_type=project&tag=all

4. 運行

由于使用了Redis,所以需要安裝redis服務器,通過以下步驟就可以將redis服務器,以及相關的依賴包安裝好。

$ sudo apt-get update$ sudo apt-get install redis-server$ sudo service redis start$ sudo pip install redis$ sudo pip install flask

 

安裝完成以后,運行,然后通過瀏覽器訪問http://127.0.0.1:8989就看到效果啦.

另有其他項目課的詳細講解和內容歡迎登陸實驗樓http://www.shiyanlou.com/courses/?course_type=project&tag=all

官方網站:實驗樓 http://www.shiyanlou.com


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 启东市| 高陵县| 宁波市| 商水县| 舟曲县| 讷河市| 东乌珠穆沁旗| 天祝| 托里县| 容城县| 呼玛县| 全椒县| 乐亭县| 陇南市| 宣恩县| 页游| 渭南市| 兰州市| 陇川县| 宁海县| 慈溪市| 蒙城县| 舒兰市| 阳新县| 墨脱县| 长子县| 镶黄旗| 兴隆县| 来安县| 离岛区| 温泉县| 陕西省| 正镶白旗| 金昌市| 沙洋县| 双辽市| 孙吴县| 鹤壁市| 阳东县| 买车| 珲春市|