Sanic WebSocket 使用

Sanic教程 2019-04-09 21:59:58 阅读(37070) 评论(4)

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。Sanic 提供了非常简洁的 websockets 抽象,让我们开发基于 WebSocket 的web应用非常容易。

Sanic WebSocket 使用

WebSocket 实例

下面是一个简单的建立 WebSocket 的例子:

from sanic import Sanic
from sanic.response import json
from sanic.websocket import WebSocketProtocol

app = Sanic()

@app.websocket('/feed')
async def feed(request, ws):
    while True:
        data = 'hello!'
        print('Sending: ' + data)
        await ws.send(data)
        data = await ws.recv()
        print('Received: ' + data)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8888, protocol=WebSocketProtocol)

上面这个app建立一个 WebSocket 的服务。也可以用 app.add_websocket_route 方法替换装饰器:

async def feed(request, ws):
    pass

app.add_websocket_route(feed, '/feed')

WebSocket 路由的处理函数需要两个参数,第一个是request对象,第二个是 WebSocket 协议对象,这个协议对象有两个方法sendrecv用来发送和接收数据。

WebSocket 的配置

通过app.config来配置 WebSocket,比如:

app.config.WEBSOCKET_MAX_SIZE = 2 ** 20
app.config.WEBSOCKET_MAX_QUEUE = 32
app.config.WEBSOCKET_READ_LIMIT = 2 ** 16
app.config.WEBSOCKET_WRITE_LIMIT = 2 ** 16

阅读Sanic 配置详细了解Sanic的配置细节。

复杂的例子

通常我们的web应用既有普通的getpost,也有websocket,比如下面这个例子:

from sanic import Sanic
from sanic.response import file

app = Sanic(__name__)


@app.route('/')
async def index(request):
    return await file('websocket.html')


@app.websocket('/feed')
async def feed(request, ws):
    while True:
        data = 'hello!'
        print('Sending: ' + data)
        await ws.send(data)
        data = await ws.recv()
        print('Received: ' + data)


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8888, debug=True)

这样一个app实例同时支持包括WebSocket在内的多种路由。

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...

  1. 1楼
    xiaohe 6年前 (2019-04-18)

    你和,我想只是通过sanic的websocket发送数据,不接收数据,我该怎么写代码呢?
    @api.websocket(‘/devices/values’)
    async def feed(request, ws):
    while True:
    logger.debug(“sending data.”)
    data = av.value(request)
    await ws.send(json.dumps(data))
    recv_data = await ws.recv()
    logger.debug(“recv data [%s].”, recv_data)
    这是我现在的代码,只有await ws.recv()调用,ws.send()才能把数据发出去,但我实际是不需要接收数据的,请问应该怎么解决呢?

    • 回复
      veelion 6年前 (2019-05-05)
      回复 @xiaohe :把recv的代码去掉,加一个await asyncio.sleep(1) 就可以只send数据了。亲测可以@app.websocket('/feed')async def feed(request, ws): while True: data = 'hello!' print('Sending: ' + data) await ws.send(data) # data = await ws.recv() # print('Received: ' + data) await asyncio.sleep(1)
  2. 2楼
    哈哈哈哈 6年前 (2019-06-13)

    楼主好。贵站风格奇清,请问是什么程序搭建的呢?是wordpress还是使用sanic呢?

    • 回复
      王平 6年前 (2019-06-13)
      回复 @哈哈哈哈 :用的wordpress的,主要后台管理方便。以后会改成Python的某一个Web框架