• sanic之websocket路由


    在某些时候,需要建立websocket路由,来建立长链接,来实时传输数据,就比如一些聊天应用,就有实时音视频,需要实时传出状态

    在sanic框架中支持两种websocket路由方式,有一种是再app中建立,另一种实在蓝图中,但是没有提供类的路由写法,都是通过函数的写法

    1.app

    from sanic import Sanic
    app = Sanic(__name__)
    
    @app.websocket('/feed')
    async def feed(request, ws):
        try:
            while True:
                data = 'hello!'
                print('Sending: ' + data)
                await ws.send(data)
                data = await ws.recv()
                print('Received: ' + data)
        except Exception as e:
            print(e)
    
    #app.add_websocket_route(feed, "/feed")
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=8009) 

    2.blueprint

    接口:ws://ip号:8001/api/student/v2/feed

    StudentVideoCallBP = Blueprint(__name__, url_prefix='/api/student/v2/')
    
    @StudentVideoCallBP.websocket('/feed')
    async def feed(ws):
        try:
            while True:
                data = 'hello!'
                print('Sending: ' + data)
                await ws.send(data)
                data = await ws.recv()
                print('Received: ' + data)
        except Exception as e:
            print(e)
    
    
    # StudentVideoCallBP.add_websocket_route(feed, "/feed")
    View Code

    3.略微复杂的一个小demo,写的是一个客户端和服务端实时通信,接口ws://10.130.145.200:8001/api/student/v2/wxlink/5ad85e49705deb4d3b98c111

    async def wxLink(request, ws, studentMid):
        student = await Student.find_one(studentMid, as_raw=True)
    #循环监听是否有客户端链接,
        while True:
    #try客户端链接状态
            try:
    #try判断是数据是否有这个学生id
                try:
                    if not student:
    #告诉客户端id错误,可能是个非法链接,然后主动断开非法链接
                        await ws.send(osjson.dumps(
                            {"studentMid": "", "videoRoomId": "", 'userSig': "", 'privateMapKey': "", 'sdkAppId': ""}))
                        break
                    Rucode = student['Rucode']
                    key = studentMid + '_' + Rucode
                    videoStatus = await ws.recv()
                    if videoStatus == '0' and str(ws.state) == 'State.OPEN':
                        data = await VideoData.get(key)
                        if data:
                            value = osjson.loads(data)
                            roomId = value['videoRoomId']
                            privateMapKey = value['privateMapKey']
                            sdkAppId = str(value['sdkAppId'])
                            userSig = str(value['user_userSig'])
                            status = value['status']
                            IsAvailable = value['IsAvailable']
                            if status == 0 and str(ws.state) == 'State.OPEN' and IsAvailable == 1:
                                await ws.send(osjson.dumps({"studentMid": "ok", 'videoRoomId': roomId, 'userSig': userSig,
                                                            'privateMapKey': privateMapKey, 'sdkAppId': sdkAppId}))
                            elif status == 0 and str(ws.state) == 'State.OPEN' and IsAvailable == 2:
                                await ws.send(osjson.dumps(
                                    {"studentMid": "ok", 'videoRoomId': "", 'userSig': "",
                                     'privateMapKey': "", 'sdkAppId': ""}))
    
    
                    # 确认接收到roomId
                    elif videoStatus == '1':
                        data = await VideoData.get(key)
                        if data:
                            value = osjson.loads(data)
                            value['status'] = 1
                            doc = osjson.dumps(value)
                            await VideoData.set(key, doc)
    
                    # 接通成功
                    elif videoStatus == '2':
                        value = await VideoData.get(key)
                        if value:
                            await VideoData.delete(key)
                        else:
                            pass
                    # 拒绝接通
                    elif videoStatus == '3':
                        req = await VideoData.get(key)
                        if req:
                            classRoomUid = osjson.loads(req)['classRoomUid']
                            await VideoData.delete(key)
                            # 推送消息
                            push_title = "I40001"
                            message = '对方已拒绝'
                            try:
                                await pushmsg(student['Rucode'], classRoomUid, push_title, message)
                            except Exception as e:
                                print(e)
                    elif videoStatus == '3':
                        req = await VideoData.get(key)
                        if req:
                            await VideoData.delete(key)
                    else:
                        pass
                except TypeError:
                    ws.close()
    #监听如果客户端断开链接,则服务端退出循环,断开链接
            except ConnectionClosed:
                break
    View Code

    4.一般websocket需要加验证,否则各种非法连接进来可咋整,加个token装饰器就可以了

    5.提供两个在线测试工具

    http://www.blue-zero.com/WebSocket/

    http://coolaf.com/tool/chattest

    注释:

    ws.state   查看ws链接状态
    ws.close 关闭链接
  • 相关阅读:
    视频:JDBCRDD源码及自定义JDBCRDD的分区策略
    聊聊spark-submit的几个有用选项
    线性求第k大
    汇编基础 第一章_总线
    长度不超过n的连续最大和___优先队列
    ISAP
    次小生成树
    k短路
    求出欧拉回路,欧拉路径
    拓扑排序bfs_dfs
  • 原文地址:https://www.cnblogs.com/zzy-9318/p/9775069.html
Copyright © 2020-2023  润新知