久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

WebSocket

 網(wǎng)海拾貝網(wǎng)絡(luò)豬 2021-04-02

目錄

一、WebSocket -網(wǎng)絡(luò)通信協(xié)議

1-1 簡(jiǎn)介

二,、Websockets servers and clients in Python

2-0 connect

2-0-1 建立一對(duì)一短連接 ?

2-0-2 建立一對(duì)一長連接

2-0-3 建立一對(duì)多長連接

2-1 asyncio

三、SocketIO

3-0 Flask-Sockets VS Flask-SocketIO

3-1 Socket.IO

3-2 python-socketio

3-2-0 安裝

3-2-1 服務(wù)端基本總結(jié) ?

3-2-3 一對(duì)多長連接

3-2 Flask-SocketIO

四、WebSocket for client - 單純用于連接的模塊

五,、Tornado - 一個(gè)支持HTTP和WebSocket的Web框架

六、Aiohttp - 基于asyncio,一個(gè)支持HTTP和WebSocket的框架


一,、WebSocket -網(wǎng)絡(luò)通信協(xié)議

WebSocket 教程 - 阮一峰

Web 基于 B/S 架構(gòu),,通常使用 HTTP 協(xié)議進(jìn)行通信,HTTP 本質(zhì)是一個(gè)單向請(qǐng)求,,若需要持續(xù)的獲取服務(wù)端的數(shù)據(jù)變化,,必須輪詢(polling)進(jìn)行數(shù)據(jù)請(qǐng)求【每隔一段時(shí)間發(fā)送request,服務(wù)器將新數(shù)據(jù)返回】,。

使用HTTP協(xié)議處理服務(wù)端數(shù)據(jù)監(jiān)控的弊端:輪詢效率低,,浪費(fèi)資源。因?yàn)楸仨毑煌=⑦B接,,或保持HTTP始終連接,。

wiki - 服務(wù)器推送方式

1-1 簡(jiǎn)介

為了解決上述的需求問題,并提高數(shù)據(jù)傳輸效率,,WebSocket 協(xié)議就出現(xiàn)了,。

WebSocket 協(xié)議下,服務(wù)端和客戶端能相互的主動(dòng)發(fā)送消息,,建立平等對(duì)話,。屬于服務(wù)器推送技術(shù)的一種。

WebSocket 一種在單個(gè) TCP 連接上進(jìn)行全雙工通訊的協(xié)議,。

WebSocket 是獨(dú)立的,、創(chuàng)建在 TCP 上的協(xié)議,和 HTTP 的唯一關(guān)聯(lián)是使用 HTTP 協(xié)議的101狀態(tài)碼進(jìn)行協(xié)議切換,,使用的 TCP 端口是80,,可以用于繞過大多數(shù)防火墻的限制。

WebSocket 使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡(jiǎn)單,,允許服務(wù)端直接向客戶端推送數(shù)據(jù)而不需要客戶端進(jìn)行請(qǐng)求,,在 WebSocket API 中,瀏覽器和服務(wù)器只需要完成一次握手,,兩者之間就直接可以創(chuàng)建持久性的連接,,并允許數(shù)據(jù)進(jìn)行雙向傳送。

二,、Websockets servers and clients in Python

websocket github

它構(gòu)建于asyncio(協(xié)程)Python的標(biāo)準(zhǔn)異步I / O框架之上,,提供了一個(gè)優(yōu)雅的基于協(xié)程的API。

即,,使用 asyncio 包裹的基本python實(shí)現(xiàn)方式

2-0 connect

2-0-1 建立一對(duì)一短連接 ?

  1. # ----------- server 端 -----------
  2. import asyncio
  3. import websockets
  4. ?
  5. async def hello(websocket, path):
  6.    print('-------- hello opened ------')
  7.    name = await websocket.recv()
  8.    print(name)
  9.    greeting = 'hello %s' % name
  10.    await websocket.send(greeting)
  11.    print(greeting)
  12. ?
  13. ?
  14. start_server = websockets.serve(hello, 'localhost', 8765)
  15. ?
  16. asyncio.get_event_loop().run_until_complete(start_server)
  17. asyncio.get_event_loop().run_forever()
  18. ?
  19. # ----------- client 端 -----------
  20. import asyncio
  21. import websockets
  22. async def hello():
  23.    async with websockets.connect(
  24.            'ws://localhost:8765') as websocket:
  25.        name = input('your name:')
  26.        await websocket.send(name)
  27.        print(name)
  28.        greeting = await websocket.recv()
  29.        print(greeting)
  30. ?
  31. ?
  32. asyncio.get_event_loop().run_until_complete(hello())

2-0-2 建立一對(duì)一長連接

  1. # ----------- server 端 -----------
  2. import asyncio
  3. import websockets
  4. async def producer_handler(websocket, path):
  5.    print('---- 建立了連接 -----')
  6.    while True:
  7.        message = input('please input:')
  8.        await websocket.send(message)
  9. ?
  10. ?
  11. start_server = websockets.serve(producer_handler, 'localhost', 8765)
  12. ?
  13. asyncio.get_event_loop().run_until_complete(start_server)
  14. asyncio.get_event_loop().run_forever()
  15. # ----------- client 端 -----------
  16. import asyncio
  17. import websockets
  18. async def consumer_handler():
  19.    async with websockets.connect(
  20.            'ws://localhost:8765') as websocket:
  21.        async for message in websocket:
  22.            print(message)
  23. asyncio.get_event_loop().run_until_complete(consumer_handler())

2-0-3 建立一對(duì)多長連接

  1. # ----------- server 端 -----------
  2. import asyncio
  3. import logging
  4. import websockets
  5. ?
  6. logging.basicConfig()
  7. ?
  8. USERS = set()
  9. ?
  10. ?
  11. async def notify_users():
  12.    # 對(duì)注冊(cè)列表內(nèi)的客戶端進(jìn)行推送
  13.    if USERS:  # asyncio.wait doesn't accept an empty list
  14.        message = input('please input:')
  15.        await asyncio.wait([user.send(message) for user in USERS])
  16. ?
  17. ?
  18. async def register(websocket):
  19.    USERS.add(websocket)
  20.    await notify_users()
  21. ?
  22. ?
  23. async def unregister(websocket):
  24.    USERS.remove(websocket)
  25.    await notify_users()
  26. ?
  27. ?
  28. async def counter(websocket, path):
  29.    # register(websocket) sends user_event() to websocket
  30.    await register(websocket)
  31.    try:
  32.        # 處理客戶端數(shù)據(jù)請(qǐng)求 (業(yè)務(wù)邏輯)
  33.        async for message in websocket:
  34.            print(message)
  35.    finally:
  36.        await unregister(websocket)
  37. ?
  38. ?
  39. asyncio.get_event_loop().run_until_complete(
  40.    websockets.serve(counter, 'localhost', 6789))
  41. asyncio.get_event_loop().run_forever()
  42. ?
  43. # ----------- client 端 -----------
  44. async def consumer_handler():
  45.    async with websockets.connect(
  46.            'ws://localhost:6789') as websocket:
  47.        async for message in websocket:
  48.            print(message)
  49. ?
  50. ?
  51. asyncio.get_event_loop().run_until_complete(consumer_handler())

2-1 asyncio

asyncio -- 異步 I/O

三,、SocketIO

python使用websocket的幾種方式

3-0 Flask-Sockets VS Flask-SocketIO

  • Flask-Sockets
    • Flask-Sockets 只是實(shí)現(xiàn)通信通道,發(fā)送的是完全取決于應(yīng)用程序,。
    • Flask-Sockets 僅僅將WebSocket協(xié)議(通過使用gevent-websocket項(xiàng)目)進(jìn)行包裝,,因此它 只適用于原生支持WebSocket協(xié)議的瀏覽器,對(duì)于那些不支持WebSocket協(xié)議的較老的瀏覽器無法使用
  • Flask-SocketIO
    • Flask-SocketIO不僅實(shí)現(xiàn)了WebSocket協(xié)議,,并且對(duì)于那些不支持WebSocket協(xié)議的舊版瀏覽器,,使用它也能夠?qū)崿F(xiàn)相同的效果。新版舊版的瀏覽器都能使用他 ,。
    • Flask-SocketIO 實(shí)現(xiàn)了SocketIO Javascript庫公開的消息傳遞協(xié)議,。
    • Flask-SocketIO 還為事件處理程序創(chuàng)建了一個(gè)類似flask的常規(guī)視圖函數(shù)的環(huán)境,包括創(chuàng)建應(yīng)用程序和請(qǐng)求上下文,。 然而,,在文檔中會(huì)介紹一些重要的例外情形。

3-1 Socket.IO

- 官方

3-2 python-socketio

python-socketio

3-2-0 安裝

  • 服務(wù)端安裝:pip install python-socketio
  • 客戶端安裝:pip install "python-socketio[client]"

安裝問題 :module 'importlib._bootstrap' has no attribute 'SourceFileLoader'

錯(cuò)誤分析:setuptools版本過久,,需要更新

解決方式:python -m ensurepip --upgrade

3-2-1 服務(wù)端基本總結(jié) ?

  1. import eventlet
  2. import socketio
  3. ?
  4. # create a Socket.IO server
  5. sio = socketio.Server()
  6. ?
  7. # wrap with a WSGI application
  8. app = socketio.WSGIApp(sio)
  9. ?
  10. ?
  11. # 事件處理函數(shù)的兩種寫法
  12. # sid:每個(gè)客戶端連接的唯一標(biāo)識(shí)符,,一個(gè)客戶端發(fā)送的所有事件具有相同的sid值
  13. @sio.event
  14. def my_event(sid, data):
  15.    pass
  16. ?
  17. ?
  18. @sio.on('my custom event')
  19. def another_event(sid, data):
  20.    pass
  21. ?
  22. ?
  23. # connetc函數(shù) 在客戶端連接時(shí)自動(dòng)調(diào)用 可用于驗(yàn)證用戶身份等
  24. # environ 為字典格式,包含請(qǐng)求信息,、http頭
  25. @sio.event
  26. def connect(sid, environ):
  27.    print('connect ', sid)
  28.    # 若返回 False 則表示拒絕與客戶端的聯(lián)系
  29.    # return False
  30.    # 拋錯(cuò),,將所有參數(shù)通過拒絕消息發(fā)送給客戶端
  31.    raise ConnectionRefusedError('authentication failed')
  32. ?
  33. ?
  34. # disconnect函數(shù) 在客戶端斷開連接時(shí)自動(dòng)調(diào)用
  35. @sio.event
  36. def disconnect(sid):
  37.    print('disconnect ', sid)
  38. ?
  39. ?
  40. # socketio.Server.emit() 發(fā)送事件
  41. # sio.emit('事件名',{'具體信息數(shù)據(jù)': '……'})
  42. sio.emit('my event', {'data': 'foobar'})
  43. # room 用于標(biāo)識(shí)應(yīng)接受該事件的客戶端sid,需要設(shè)置客戶端的sid,,若省略則表示廣播事件
  44. sio.emit('my event', {'data': 'foobar'}, room='user_sid')
  45. # callback 回調(diào)函數(shù),,將在客戶端處理事件后調(diào)用該函數(shù),客戶端返回的任何值都將作為參數(shù)給予該回調(diào)函數(shù),。
  46. # 若在廣播的情況下使用回調(diào),,則服務(wù)端將有大量的調(diào)用次數(shù)
  47. sio.emit('my event', {'data': 'foobar'}, callback=my_event)
  48. ?
  49. ?
  50. # namespace 命名空間
  51. # client 為每個(gè)連接制定不同的命名空間,來打開多個(gè)連接,,命名空間將作為主機(jī)名和端口后的路徑名
  52. # http://:8000/chat
  53. @sio.event(namespace='/chat')
  54. def my_custom_event(sid, data):
  55.    pass
  56. ?
  57. ?
  58. @sio.on('my custom event', namespace='/chat')
  59. def my_custom_event(sid, data):
  60.    pass
  61. ?
  62. ?
  63. # socketio.Namespace 基于類的命名空間
  64. # 注意:基于類的命名空間為單例,,所以命名空間實(shí)例不能用于存儲(chǔ)客戶端的特定消息
  65. class MyCustomNamespace(socketio.Namespace):
  66.    # 服務(wù)器接受的任何事件,都將調(diào)用 on_ 前綴的事件名方法
  67.    # 若接受到的事件名在類內(nèi)無匹配on前綴方法,,則忽略,。
  68.    def on_connect(self, sid, environ):
  69.        pass
  70. ?
  71.    def on_disconnect(self, sid):
  72.        pass
  73. ?
  74.    # my_event 事件觸發(fā) on_my_event 方法的執(zhí)行
  75.    def on_my_event(self, sid, data):
  76.        self.emit('my_response', data)
  77. ?
  78. ?
  79. sio.register_namespace(MyCustomNamespace('/test'))
  80. ?
  81. ?
  82. # room 指定用戶組
  83. # socketio.Server.enter_room() 和 socketio.Server.leave_room()方法管理其中的客戶端
  84. @sio.event
  85. def begin_chat(sid):
  86.    sio.enter_room(sid, 'chat_users')
  87. ?
  88. ?
  89. @sio.event
  90. def exit_chat(sid):
  91.    sio.leave_room(sid, 'chat_users')
  92. ?
  93. ?
  94. # skip_sid 用于跳過該sid的客戶端,不進(jìn)行消息推送
  95. @sio.event
  96. def my_message(sid, data):
  97.    sio.emit('my reply', data, room='chat_users', skip_sid=sid)
  98. ?
  99. ?
  100. # session 用戶信息存儲(chǔ)和檢索
  101. # 注意:客戶端斷開連接時(shí),,會(huì)破壞用戶會(huì)話的內(nèi)容,。
  102. #       特別是,當(dāng)客戶端在意外斷開與服務(wù)器的連接后重新連接時(shí),,不會(huì)保留用戶會(huì)話內(nèi)容,。
  103. @sio.event
  104. def connect(sid, environ):
  105.    username = environ
  106.    # username = authenticate_user(environ)
  107.    sio.save_session(sid, {'username': username})
  108. ?
  109. ?
  110. @sio.event
  111. def message(sid, data):
  112.    session = sio.get_session(sid)
  113.    print('message from ', session['username'])
  114. ?
  115. ?
  116. # 基于上下文,管理session
  117. @sio.event
  118. def connect(sid, environ):
  119.    username = environ
  120.    # username = authenticate_user(environ)
  121.    with sio.session(sid) as session:
  122.        session['username'] = username
  123. ?
  124. ?
  125. @sio.event
  126. def message(sid, data):
  127.    with sio.session(sid) as session:
  128.        print('message from ', session['username'])

3-2-3 一對(duì)多長連接

3-2 Flask-SocketIO

Flask-SocketIO - github

  1. from flask import Flask, render_template
  2. from flask_socketio import SocketIO
  3. ?
  4. app = Flask(__name__)
  5. app.config['SECRET_KEY'] = 'secret!'
  6. socketio = SocketIO(app)
  7. ?
  8. ?
  9. @socketio.on('connect')
  10. def connect():
  11.    print('connection established')
  12. ?
  13. ?
  14. @socketio.on('my_event')
  15. def handle_json(json):
  16.    print('received json: ' + str(json))
  17. ?
  18. ?
  19. @socketio.on('disconnect')
  20. def test_disconnect():
  21.    print('Client disconnected')
  22. ?
  23. ?
  24. if __name__ == '__main__':
  25.    socketio.run(app)
  26. ?

 

四,、WebSocket for client - 單純用于連接的模塊

websocket-client github

安裝:Type "python setup.py install" or "pip install websocket-client" to install.

五,、Tornado - 一個(gè)支持HTTP和WebSocket的Web框架

Tornado 官方文檔

WebSocket - Tornado 的基本實(shí)現(xiàn)總結(jié)

六、Aiohttp - 基于asyncio,,一個(gè)支持HTTP和WebSocket的框架

aiohttp 官方文檔

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多