如何在同一客户端中拥有套接字连接和 websocket 连接?

How can I have socket connection and a websocket connection in same client?

我正在尝试让套接字服务器与 websocket 服务器通信。但是我无法让它工作。

首先,我在本地主机端口 40404 上开始使用套接字连接到服务器 运行ning。

然后我在本地主机端口 1236 上启动一个 websocket 服务器。

我有两个异步函数附加到事件循环:

一个监听来自套接字服务器的传入消息并将它们打印到终端。

另一个侦听到 websocket 服务器的传入消息并将它们发送到套接字服务器。

我有一个 Javascript 客户端连接到 websocket 服务器。

当我运行我的代码时,我得到了到套接字服务器的连接和来自那一边的一些响应。但是没有启动 websocket 服务器。

我没有收到任何错误。

我做错了什么?

这是代码:

import socket
import asyncio
import websockets

#Gets any responses from the external socket server
async def get_resp():
    while True:
        resp = s.recv(5000).decode()
        print(resp)
        await asyncio.sleep(1)
 
#Gets any responses from the external websocket server and send it to socket server
async def listen_for_websocket(websocket, path):
    for message in websocket:
        json_obj = json.loads(message)
        print(json_obj["Message"])

        #The message from the JS client is in json format
        message = json_obj["Message"]
        message = message + '\n'
        message = message.encode()

        #Foreward the message to the socket server
        s.send(message)

        #Send a response back to the websocket
        await websocket.send('{"Message":"Thanks for your message"}')

loop = asyncio.get_event_loop()

try:
    #Start up connection with external socket server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    #Stuf needed by the socket server
    s.connect(('localhost',40404))
    s.send(b'version [["0.1.4"],{}]\n')
    s.send(b'name [["Python"],{}]\n')

    #Starts connection to websocket
    start_server = websockets.serve(listen_for_websocket,'localhost',1236)

    asyncio.ensure_future(get_resp())
    loop.run_until_complete(start_server)
    loop.run_forever()

您与套接字服务器的连接不是异步的。阻止对 recv 的调用会停止事件循环并阻止 websockets 部分正常运行。

您不应调用 socket.socket 并直接使用套接字,而应调用 asyncio.open_connection。例如(未经测试):

async def get_resp(reader):
    while True:
        resp = await reader.read(5000)
        if resp == b'':
            break
        print(resp.decode())

async def listen_for_websocket(websocket, path, writer):
    async for message in websocket:
        json_obj = json.loads(message)
        message = json_obj["Message"] + '\n'
        writer.send(message.encode())
        await websocket.send('{"Message":"Thanks for your message"}')

async def main():
    reader, writer = await asyncio.open_connection('localhost', 40404)
    writer.write(b'version [["0.1.4"],{}]\n')
    writer.write(b'name [["Python"],{}]\n')
    await websockets.serve(
        lambda w, p: listen_for_websocket(w, p, writer),
        'localhost', 1236
    )
    # waits as long as the server is up
    await get_resp(reader)

asyncio.run(main())