国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

由淺入深介紹 Python Websocket 編程

這篇具有很好參考價值的文章主要介紹了由淺入深介紹 Python Websocket 編程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


1. 為什么使用 Websocket ?

1.1 websocket 協(xié)議簡介

Websocket協(xié)議是對http的改進,可以實現(xiàn)client 與 server之間的雙向通信; websocket連接一旦建立就始終保持,直到client或server 中斷連接,彌補了http無法保持長連接的不足,方便了客戶端應用與服務器之間實時通信。

適用場景
  • html頁面實時更新, 客戶端的html頁面內,用` javascript` 與 server 建立websocket連接,實現(xiàn)頁面內容的實時更新。Websocket 非常適合網(wǎng)頁游戲、聊天、證券交易等實時應用。
  • 要求保持長連接的實時通信的應用場景。 如基于位置的服務應用,物聯(lián)網(wǎng),多方協(xié)作軟件,在線教育,帶社交屬性的手機APP等。

實時更新數(shù)據(jù)場景,為什么不使用AJAX?
AJAX 采用http, 如果要實時更新頁面,則需要不斷地發(fā)送http 請求,無論是否有數(shù)據(jù)更新,產生大量冗余通信流量。而websocket是長連接雙向通信,有數(shù)據(jù)更新時,服務器向客戶機發(fā)送通知。

1.2 基本原理

基于TCP,一次握手就能建立連接,支持雙向通信,可保持長連接。

python websocket,Python網(wǎng)絡通信編程,websocket,python,網(wǎng)絡協(xié)議,javascript

WebSocket 握手請求消息示例::

GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket

如果 Server 接收連接,返回響應

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=

響應碼為101,表示切換為websocket 協(xié)議。

websocket 已得到主流瀏覽器,各編程語言的廣泛支持,基本都提供了WebSocket高階編程API,在一般場合下,可以替代socket低階函數(shù)編程。python 提供了更簡潔的編程實現(xiàn)方式。下面展示了實例代碼方式,說明如何開發(fā) Python websocket 服務器代碼,python websocket 客戶端, 以及javascript websocket 代碼。

2. 如何用 Python 搭建 Websocket 服務

python 第3方庫 websockets 提供了websocket 實現(xiàn)框架,支持asyncio, 性能強大,穩(wěn)定性好,可以用于生產環(huán)境。

2.1 安裝websockets包

pip install websockets

2.2 編寫 server 端代碼

Websocket服務端代碼是面向多用戶的長連接,因此本文采用了python3.7 版本的 asyncio 異步方式編寫 websocket server 代碼。

服務端也可使用 ThreadPoolExecutor 線程池方式同時處理多連接的場景,用戶較多時,性能明顯不如asyncio異步方式。

websockets 模塊 server端的主要方法:

  • recv() 收消息
  • send() 發(fā)送消息
  • serve() 創(chuàng)建 server 對象

實現(xiàn)步驟:

  1. 編寫websocket 異步任務處理函數(shù)handler
  2. 創(chuàng)建1個websocket server 對象
  3. 異步運行 server對象

websocket 地址格式:

  • ws://主機地址:端口號
  • wss://主機地址:端口號, wss表示此連接為https 連接。

下面是具體的代碼 server.py

#!/usr/bin/python3
# 主要功能:創(chuàng)建1個基本的websocket server, 符合asyncio 開發(fā)要求
import asyncio
import websockets
from datetime import datetime


async def handler(websocket):
    data = await websocket.recv()
    reply = f"Data received as \"{data}\".  time: {datetime.now()}"
    print(reply)
    await websocket.send(reply)
    print("Send reply")


async def main():
    async with websockets.serve(handler, "localhost", 9999):
        await asyncio.Future()  # run forever

if __name__ == "__main__":
    asyncio.run(main())


服務端handler函數(shù)代碼還有1種寫法,適用性更好。

async def handler(websocket):
    async for message in websocket:
	    reply = f"Data received as \"{message}\".  time: {datetime.now()}"
	    print(reply)
        await websocket.send(reply)

Websocket協(xié)議本身有心跳機制、連接檢測機制,服務端無須關心客戶端狀態(tài),一旦有異常,會自動斷開連接。

Websockets提供了交互式測試命令,現(xiàn)在可以快速測試一下服務端是否能正常工作:
(1) 啟動服務器: python server.py
(2) 通過命令行連接服務端,并向發(fā)送hello, world 消息,可以看到,收到了服務器的響應。

D:\workplace\python\projects\websock>python -m websockets ws://localhost:9999
Connected to ws://localhost:9999.
> hello, world
< Data received as "hello, world".  time: 2023-04-01 09:24:14.787357
Connection closed: 1000 (OK).

當然實際應用時,應按下面步驟來編寫客戶端代碼。

3. Python websocket 客戶端實現(xiàn)代碼

websockets 客戶端提供的主要方法:

  • connect() 建立與服務器的連接
  • recv(), send() 收發(fā)消息
  • close() 顯式地關閉連接

下面看一下示例 client.py

import asyncio
import websockets
import time


async def ws_client(url):
    for i in range(1, 40):
        async with websockets.connect(url) as websocket:
            await websocket.send("Hello, I am PyPy.")
            response = await websocket.recv()
        print(response)
        time.sleep(1)

asyncio.run(ws_client('ws://localhost:9999'))


4. Javascript websocket 客戶端實現(xiàn)代碼

目前主流的瀏覽器都支持websocket協(xié)議。

Javascript websocket 對象的主要屬性與方法:
請參考菜鳥教程的這篇文章:https://www.runoob.com/html/html5-websocket.html

示例代碼: client.html

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <title>websocket demo</title>
  	<meta name="viewport" content="width=device-width, initial-scale=1">
 	 <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
	<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js">		</script>
	<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
  	<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>

    <script type="text/javascript">
        function WebSocketTest() {
            text = document.getElementById("div_text");
            if ("WebSocket" in window) {
                // 打開一個 web socket
                var ws = new WebSocket("ws://localhost:9999/handler");

                ws.onopen = function () {
                    // Web Socket 已連接上,使用 send() 方法發(fā)送數(shù)據(jù)
                    ws.send("Javscript發(fā)送的數(shù)據(jù)");
                    text.innerHTML = "數(shù)據(jù)發(fā)送中...";
                    alert("數(shù)據(jù)發(fā)送中...");
                };

                ws.onmessage = function (evt) {
                    var received_msg = evt.data;
                    text.innerHTML = "收到的數(shù)據(jù):" + received_msg;
                    alert("數(shù)據(jù)已接收...");
                };

                ws.onclose = function () {
                    // 關閉 websocket
                    text.innerHTML = "連接已關閉...";
                    alert("連接已關閉...");
                };
            }

            else {
                // 瀏覽器不支持 WebSocket
                alert("您的瀏覽器不支持 WebSocket!");
            }
        }
    </script>

</head>

<body>

    <div class="col-md-6 m-5 p-2" id="div_ws">
        <a class="btn btn-primary" href="javascript:WebSocketTest()">連接WebSocket</a>
    </div>
    <div class="col-md-6 border border-primary mx-5 p-2 " id="div_text" style="margin:20px;height:100px;">
        display communicate text
    </div>

</body>

</html>

5. 測試websocket

上述3個文件都放在同1個目錄下,打開兩個終端窗口,先運行server.py, 再運行 client,py。
Output結果
python websocket,Python網(wǎng)絡通信編程,websocket,python,網(wǎng)絡協(xié)議,javascript
在chrome 或edge 中運行client.html, 可以看到websocket 連接建立,發(fā)送,接收,關閉各階段的狀態(tài)。
python websocket,Python網(wǎng)絡通信編程,websocket,python,網(wǎng)絡協(xié)議,javascript
能夠看到,服務器與客戶端之間的通信是雙向的,而且是長連接,客戶端斷開后,服務器仍然保持偵聽狀態(tài),而且不需要accept操作。websocket發(fā)送、接收文件也不需要 socket 對發(fā)送窗口 buffer 進行控制,因此是 socket 開發(fā)非常好的替代。

注:Python異步websocket服務器最終性能與代碼質量、服務器硬件、網(wǎng)絡等緊密相關,可以使用 Websocket-benchmarker 測試工具來測試服務器。

6. 服務器向客戶端廣播消息

websockets 模塊支持向所有連接的客戶廣播消息,
用1個簡單的例子來演示,實現(xiàn)步驟:

  • 保存每個 websocket 客戶連接
  • 向每個客戶發(fā)送消息

將前面的server,.py 代碼修改后如下:

#!/usr/bin/python3
# 主要功能:創(chuàng)建1個基本的websocket server, 符合asyncio 開發(fā)要求
import asyncio
import websockets
from datetime import datetime

# Set of connected clients
connected_clients = set()

async def handler(websocket, path):
    # Add the client to the connected clients set
    connected_clients.add(websocket)    
    try:
        # Keep listening for incoming messages from the client
        async for message in websocket:
            # Broadcast the message to all connected clients
            await broadcast(message)
    finally:
        connected_clients.remove(websocket) 
        
async def broadcast(message):
    # Broadcast the message to all connected clients
    for client in connected_clients:
        await client.send(message)

async def main():
    async with websockets.serve(handler, "localhost", 9998):
        await asyncio.Future()  # run forever
        loop = asyncio.get_running_loop() #獲取當前event_loop對象
        loop.create_task(broadcast())     # 添加新的異步廣播任務

if __name__ == "__main__":
    asyncio.run(main())

本例中,當服務器收到1條消息時,會廣播給所有用戶。文章來源地址http://www.zghlxwxcb.cn/news/detail-780629.html

到了這里,關于由淺入深介紹 Python Websocket 編程的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 大學生精通Python從由淺入深(Python基礎篇)

    大學生精通Python從由淺入深(Python基礎篇)

    看到這位 頭發(fā)濃密 大叔了嗎!1989年,為了打發(fā)圣誕節(jié)假期,龜叔(吉多·范·羅蘇姆)開始寫Python語言的編譯器 。 1991年 ,第一個Python編譯器誕生 Python這個名字,來自龜叔所摯愛的電視劇Monty Python’s Flying Circus (蒙蒂·蟒蛇的飛行馬戲團) 我們?yōu)槭裁匆獙W習這一項語言,Pytho

    2024年02月10日
    瀏覽(21)
  • 由淺入深掌握各種 Python 進程間通信方式(建議收藏)

    由淺入深掌握各種 Python 進程間通信方式(建議收藏)

    轉載本文請注明 CSDN 鏈接處: https://blog.csdn.net/captain5339/article/details/129099833 Python代碼效率由于受制于GIL全局鎖限制,多線程不能利用多核CPU來加速,而 多進程 方式卻可以繞過GIL限制, 發(fā)揮多CPU加速的優(yōu)勢,達到提高程序的性能的目的。 然而進程間通信卻是不得不考慮的問題。

    2024年02月02日
    瀏覽(13)
  • Python+大數(shù)據(jù)-大學生精通Python從由淺入深(Python基礎篇)

    Python+大數(shù)據(jù)-大學生精通Python從由淺入深(Python基礎篇)

    看到這位 頭發(fā)濃密 大叔了嗎!1989年,為了打發(fā)圣誕節(jié)假期,龜叔(吉多·范·羅蘇姆)開始寫Python語言的編譯器 。 1991年 ,第一個Python編譯器誕生 Python這個名字,來自龜叔所摯愛的電視劇Monty Python’s Flying Circus (蒙蒂·蟒蛇的飛行馬戲團) 我們?yōu)槭裁匆獙W習這一項語言,Pytho

    2024年02月13日
    瀏覽(26)
  • Docker由淺入深(一)

    容器化技術介紹 介紹容器化之前,我們得先知道,為什么會出現(xiàn)容器化,容器化之前都經歷了什么 物理機時代 部署非常慢 成功很高 浪費資源 難于擴展與遷移 受制于硬件 虛擬化時代 在同一個物理機上安裝多個虛擬機,每個虛擬機安裝操作系統(tǒng)和應用, 虛擬機之間物理資源

    2024年02月03日
    瀏覽(39)
  • 由淺入深了解HashMap源碼

    由淺入深了解HashMap源碼

    ? ? ? ?由經典面試題引入,講解一下HashMap的底層數(shù)據(jù)結構?這個面試題你當然可以只答,HashMap底層的數(shù)據(jù)結構是由(數(shù)組+鏈表+紅黑樹)實現(xiàn)的,但是顯然面試官不太滿意這個答案,畢竟這里有一個坑需要你去填,那就是在回答HashMap的底層數(shù)據(jù)結構時需要考慮JDK的版本,因

    2023年04月13日
    瀏覽(28)
  • 由淺入深Netty代碼調優(yōu)

    由淺入深Netty代碼調優(yōu)

    序列化,反序列化主要用在消息正文的轉換上 序列化時,需要將 Java 對象變?yōu)橐獋鬏數(shù)臄?shù)據(jù)(可以是 byte[],或 json 等,最終都需要變成 byte[]) 反序列化時,需要將傳入的正文數(shù)據(jù)還原成 Java 對象,便于處理 目前的代碼僅支持 Java 自帶的序列化,反序列化機制,核心代碼如

    2024年02月05日
    瀏覽(23)
  • React - redux 使用(由淺入深)

    React - redux 使用(由淺入深)

    中文文檔: http://www.redux.org.cn/ 英文文檔: https://redux.js.org/ Github: https://github.com/reactjs/redux 可直接參照 目錄十 進行使用 react-redux redux 是一個專門用于做狀態(tài)管理的JS庫(不是react插件庫)。 它可以用在 react, angular, vue 等項目中, 但基本與 react 配合使用。 作用: 集中式管理 re

    2024年02月07日
    瀏覽(24)
  • 【個人筆記】由淺入深分析 ClickHouse

    項目中不少地方使用到ClickHouse,就對它做了一個相對深入一點的了解和研究。并對各種知識點及整理過程中的一些理解心得進行了匯總并分享出來,希望對其他同學能有幫助。 本文主要講解ClickHouse的特點、讀寫過程、存儲形式、索引、引擎、物化視圖等特性。 適合 入門和

    2024年01月20日
    瀏覽(29)
  • 由淺入深理解C#中的事件

    本文較長,給大家提供了目錄,可以直接看自己感興趣的部分。 前面介紹了C#中的委托,事件的很多部分都與委托類似。實際上,事件就像是專門用于某種特殊用途的簡單委托,事件包含了一個私有的委托,如下圖所示: 有關事件的私有委托需要了解的重要事項如下: 1、事

    2024年02月03日
    瀏覽(30)
  • Springboot3+EasyExcel由淺入深

    Springboot3+EasyExcel由淺入深

    環(huán)境介紹 技術棧 springboot3+easyexcel 軟件 版本 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3 EasyExcel是一個基于Java的、快速、簡潔、解決大文件內存溢出的Excel處理工具。 他能讓你在不用考慮性能、內存的等因素的情況下,快速完成Excel的讀、寫等功能。 官網(wǎng)https://easyexcel.opensource.ali

    2024年01月16日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包