websocket的基本概念及基本用法


0 前言

本文为websocket系列文章的第一篇,主要讲解一些websocket的基本概念和使用方法。

1 概述

1.1 为什么需要websocket

WebSocket 是一种网络通信协议,它允许在客户端和服务器之间建立一个持久的连接,使得数据可以实时、双向地传输,从而为需要快速、连续交互的应用如在线游戏、聊天应用和实时数据更新提供了一个高效、低延迟的通信解决方案。

1.2 websockets可以发送的数据格式

  • 文本数据:适用于发送JSON、XML、HTML或其他文本格式的数据。
  • 二进制数据:适用于传输图像、视频、音频或其他二进制文件。比如:
import websockets
import asyncio
import os

async def send_file(websocket, file_path):
    with open(file_path, 'rb') as f:
        binary_data = f.read()
        await websocket.send(binary_data)
        print(f"Sent file: {file_path}")

async def main():
    uri = "ws://localhost:6789"
    async with websockets.connect(uri) as websocket:
        # 替换为你的图片或音频文件路径
        image_path = 'path/to/your/image.png'
        audio_path = 'path/to/your/audio.mp3'
        
        # 发送图片
        await send_file(websocket, image_path)
        # 发送音频
        await send_file(websocket, audio_path)

asyncio.run(main())

在这个代码示例里,f 是一个文件对象,它提供了对文件的访问和操作。'rb’模式表示正在以二进制读取模式打开文件,在二进制模式下,文件内容被读取为原始的字节序列。这意味着文件中的数据将按其在磁盘上存储的原始形式被读取,而不进行任何解码或解释。这对于处理非文本文件(如图片、音频、视频等)尤为重要,因为这些文件包含的数据不是简单的字符编码,而是二进制数据。f.read() 方法用于从文件中读取数据。在二进制模式下,无论文件内容是什么,read() 方法都将数据作为字节对象返回。

2 使用案例

2.1 案例1

服务端代码:

import asyncio
from websockets.asyncio.server import serve
import time

async def echo(websocket):
    print("Connected!")
    while True:
        message  = await websocket.recv()
        time.sleep(1)
        print(f"Received: {message}")
        await websocket.send(f'Hello {message}')

async def main():
    async with serve(echo, "localhost", 8765):
        await asyncio.get_running_loop().create_future()  # run forever

asyncio.run(main())

客户端代码:

from websockets.sync.client import connect

def hello():
    with connect("ws://localhost:8765") as websocket:
        while True:
            websocket.send("world!")
            message = websocket.recv()
            print(f"Received: {message}")

hello()

代码讲解:

  • 在案例1的服务端和客户端的代码中,都使用无限循环的方式来接收和发送消息,这没法好说的。
  • 如果将服务端的无限循环的方式去掉(注释掉 while True),那客户端发送消息只能进行一次交互就会断开连接。这是因为在 echo 函数中,只处理了一次消息接收和发送。处理完一次后,函数就结束了,导致 WebSocket 连接关闭。
  • 如果将客户端的无限循环的当时去掉(注释掉 while True),那客户端和服务端之间也只是交互一次,这是因为客户端只发送了一次请求。

2.2 案例2

服务端代码:

import asyncio
from websockets.asyncio.server import serve
import time

async def echo(websocket):
    print("Connected!")
    async for message in websocket:
        time.sleep(1)
        print(f"Received: {message}")
        await websocket.send(f'Hello {message}')

async def main():
    async with serve(echo, "localhost", 8765):
        await asyncio.get_running_loop().create_future()  # run forever

asyncio.run(main())

客户端代码:

from websockets.sync.client import connect

def hello():
    with connect("ws://localhost:8765") as websocket:
        while True:
	        websocket.send("world!")
	        message = websocket.recv()
	        print(f"Received: {message}")

hello()

代码讲解:

案例2的代码与案例1最大的不同就是服务端的代码,它使用了Python的asyncio库和websockets库来异步地从WebSocket连接中接收消息。当使用async for message in websocket:时,它会不断地等待和接收来自WebSocket服务端的消息,直到连接关闭。这种方式很适合处理连续的数据流,如实时聊天消息或股票价格更新。

这种异步处理方式的优势在于它不会阻塞整个程序的运行,允许同时执行其他任务,提高了程序的效率和响应性。

总结

本文讲解的内容很简单,更多的是为了加深对websocket的理解所做的一些笔记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值