Python3如何处理websockets中断开连接的用户?

2024-07-03 08:05:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做什么:

如何处理一个用户使用websockets从应用程序断开连接,但仍然允许其他连接到服务器的用户继续?如果我运行此命令,我的所有用户都可以连接,但是当一个用户断开连接时,服务器会抛出一个异常:

websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1001 (going away), no reason

这是我的密码:

#!/usr/bin/env python

import asyncio
import websockets
import json
import ssl
import pathlib
users = {}
connected = set()
async def sendTo(websocket, message):
    await websocket.send(json.dumps(message))

async def signaling(websocket, path):
    while(True):
        #get message from client
        message = await websocket.recv()
        #decode message
        try:
            data = json.loads(message)
        except:
            print("Not valid json")

        print(message)
        if data['type'] == "login":
            if data['name'] in users:
                await sendTo(websocket,{"type": "login", 
                        "Success":False})
                print("sentTo Failed, username already taken")
            else:
                users[data['name']] = {"websocket": websocket}
                await sendTo(websocket, {"type": "login", 
                        "Success":True})
                #send all of the users a list of names that they can connect to

                for key, val in users.items():    
                    await sendTo(val['websocket'], {"type":"userLoggedIn",
                                 "names":list(users.keys())})
        elif data['type'] == "offer":
            print("Sending offer to: {}".format(data['sentTo']))
            #if UserB exists then send him offer details 
            conn = users[data['sentTo']]['websocket']
            users[data['name']]['sentTo'] = data['sentTo']
            if conn is not None:
                #setting that UserA connected with UserB 
                #websocket['otherName'] = data['name']
                #send to connection B
                await sendTo(conn, {"type": "offer", 
                        "offer":data['offer'],
                        "name":data['name']})#send the current connections name
                #add other user to my list for retreaval later
                print("offerFrom: {}, offerTo: {}".format(data['name'], data['sentTo']))

        elif data['type'] == "answer":
            print("Sending answer to: {}".format(data['sentTo']))
            conn = users[data['sentTo']]['websocket']
            users[data['name']]['sentTo'] = data['sentTo']
            if conn is not None:
                #setting that UserA connected with UserB 
                await sendTo(conn, {"type": "answer", 
                        "answer":data['answer']})
            #add other user to my list for retreaval later
            print("answerFrom: {}, answerTo: {}".format(data['name'], data['sentTo']))
        elif data['type'] == "candidate":
            print("Sending candidate ice to: {}".format(users[data['name']]['sentTo']))
            sendingTo = users[data['name']]['sentTo']#Who am I sending data to
            conn = users[sendingTo]['websocket']
            if conn is not None:
                #setting that UserA connected with UserB 
                await sendTo(conn, {"type": "candidate", 
                        "candidate":data['candidate']})
            print("candidate ice From: {}, candidate ice To: {}".format(data['name'], users[data['name']]['sentTo']))

        elif data['type'] == "candidate":
            print("Disconnecting: {}".format(users[data['name']]['sentTo']))
            sendingTo = users[data['name']]['sentTo']#Who am I sending data to
            conn = users[sendingTo]['websocket']
            if conn is not None:
                #setting that UserA connected with UserB 
                await sendTo(conn, {"type": "leave"})
        else:
            print("Got another Message: {}".format(data))

        #closing the socket is handled?
        #await websocket.send(json.dumps({"msg": "Hello_World!!!!"}))
if __name__ == "__main__":
    print("Starting Server")
    #path.abspath("/opt/cert")
    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    ssl_context.load_cert_chain(
    pathlib.Path("/opt/cert/nginx-selfsigned.crt").with_name('nginx-selfsigned.crt'), pathlib.Path("/opt/cert/nginx-selfsigned.key").with_name('nginx-selfsigned.key'))

    asyncio.get_event_loop().run_until_complete(
        websockets.serve(signaling, '192.168.11.138', 8765, ssl=ssl_context))
    asyncio.get_event_loop().run_forever()
    print('ended')
    users = {}

我尝试的

我尝试在等待消息并跳出循环时添加一个异常,但它似乎不允许其他用户继续使用该应用程序。你知道吗


Tags: tonameformatssldataiftypeawait