从 Windows 收听 websockets 运行 Raspbian

Listen to websockets running Raspbian from Windows

我使用 Python 的 asynciowebsockets 模块创建了一个 websocket。该服务器在同一台机器上正常工作。这是服务器的实际代码:

import sys
import os
import asyncio
import websockets

@asyncio.coroutine
def receive(websocket, path):
    data = yield from websocket.recv()
    print('< {}'.format(data))

    output = 'Sent data from server: {}'.format(data)

    yield from websocket.send(output)
    print('> {}'.format(output))


start_server = websockets.serve(receive, '127.0.0.1', 8765)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

它运行正常,来自同一台机器上的客户端的连接没有任何问题。

但是当我尝试从 LAN 网络上的客户端访问它时,它会生成一个 ConnectionRefusedError。这是客户端代码:

import asyncio
import websockets

@asyncio.coroutine
def hello():
    websocket = yield from websockets.connect(
        'ws://192.168.0.26:8765')

    try:
        name = input("What's your name? ")

        yield from websocket.send(name)
        print("> {}".format(name))

        greeting = yield from websocket.recv()
        print("< {}".format(greeting))

    finally:
        yield from websocket.close()

asyncio.get_event_loop().run_until_complete(hello())

我已经在 Raspbian 上安装了 ufw 以使用此命令启用端口 8765:

ufw allow 8765

但是没用。在 Windows 机器上,命令

nmap -p 8765 192.168.0.26

生成此结果:

PORT        STATE    SERVICE
8765/tcp    closed   ultraseek-http

还有……命令

ufw status

有人可以提供一些建议来解决客户端和服务器之间的通信问题。

这是一个问题:

start_server = websockets.serve(receive, '127.0.0.1', 8765)

你已经告诉 websockets 只在 127.0.0.1 上 listen,因此你只能接收来自本地主机的连接,并且只能在旧的 IPv4 上。本地主机 IPv6 连接(默认)和来自其他计算机的所有连接都将收到连接被拒绝的错误。

如果你想接收来自本地机器外部的连接,你应该将 Host 设置为 None 或空字符串。这将接受来自任何地方的连接,包括 IPv6 和 IPv4,当然要遵守任何防火墙规则。

start_server = websockets.serve(receive, None, 8765)

主机和端口直接传递给 asyncio.create_server() 文件主机为:

  • If host is a string, the TCP server is bound to a single network interface specified by host.
  • If host is a sequence of strings, the TCP server is bound to all network interfaces specified by the sequence.
  • If host is an empty string or None, all interfaces are assumed and a list of multiple sockets will be returned (most likely one for IPv4 and another one for IPv6).