【问题标题】:Socket.IO Client Library in Python [closed]Python中的Socket.IO客户端库[关闭]
【发布时间】:2011-06-13 07:44:06
【问题描述】:

谁能推荐一个用于 Python 的 Socket.IO 客户端库? 我环顾四周,但我唯一能找到的要么是服务器实现,要么依赖于诸如 Twisted 之类的框架。

我需要一个不依赖其他框架的客户端库。

仅使用多种连接类型中的一种是不够的,因为 python 客户端将需要使用多个 socketio 服务器,例如,其中许多服务器不支持 websocket。

【问题讨论】:

    标签: python client-server socket.io


    【解决方案1】:

    你看过gevent-socketio吗?

    希望对你有帮助。

    【讨论】:

    • gevent-socketio 不是 Python 的 Socket.IO 客户端库...它是 Python 的 Socket.IO 服务器库
    • +1 这对我很有帮助,谢谢。
    【解决方案2】:

    首先,我不确定为什么你们的一些 Socket.IO 服务器不支持 websockets...Socket.IO 的目的是通过提供抽象的 Web 应用程序的前端浏览器开发更容易Socket.IO 服务器提供的实时数据流的接口。也许 Socket.IO 不是您应该为您的应用程序使用的?除此之外,让我试着回答你的问题......

    此时,没有任何适用于 Python 的 Socket.IO 客户端库(gevent-socketio 不是适用于 Python 的 Socket.IO client 库......它是一个 Socket. Python 的 IO server 库)。现在,您必须将一些原始代码拼凑在一起,以便在接受各种连接类型的同时直接作为客户端与 Socket.IO 交互。

    我知道您正在寻找一种适用于各种连接类型(WebSocket、长轮询等)的万能药,但由于目前尚不存在这样的库,我至少可以为您提供根据我的经验,一些关于使用 WebSocket 连接类型的指导。

    对于 WebSocket 连接类型,在 Python 中创建一个 WebSocket 客户端。从命令行安装这个 Python WebSocket 客户端包 here 和 pip,这样它就在你的 python 路径上,如下所示:

    pip install -e git+https://github.com/liris/websocket-client.git#egg=websocket

    完成后尝试以下操作,将 SOCKET_IO_HOST 和 SOCKET_IO_PORT 替换为 Socket.IO 服务器的适当位置:

    import websocket
    
    SOCKET_IO_HOST = "127.0.0.1"
    SOCKET_IO_PORT = 8080
    
    socket_io_url = 'ws://' + SOCKET_IO_HOST + ':' + str(SOCKET_IO_PORT) + '/socket.io/websocket'
    
    ws = websocket.create_connection(socket_io_url)
    

    此时,您可以直接从 Python 与 Socket.IO 服务器进行交互。要向 Socket.IO 服务器发送消息,只需通过此 WebSocket 连接发送消息。为了让 Socket.IO 服务器正确地解释从 Python Socket.IO 客户端通过此 WebSocket 传入的消息,您需要遵守 Socket.IO 协议并对您可能通过 WebSocket 连接发送的任何字符串或字典进行编码。例如,在完成上述所有操作后,请执行以下操作:

    def encode_for_socketio(message):
        """
        Encode 'message' string or dictionary to be able
        to be transported via a Python WebSocket client to 
        a Socket.IO server (which is capable of receiving 
        WebSocket communications). This method taken from 
        gevent-socketio.
        """
        MSG_FRAME = "~m~"
        HEARTBEAT_FRAME = "~h~"
        JSON_FRAME = "~j~"
    
        if isinstance(message, basestring):
                encoded_msg = message
        elif isinstance(message, (object, dict)):
                return encode_for_socketio(JSON_FRAME + json.dumps(message))
        else:
                raise ValueError("Can't encode message.")
    
        return MSG_FRAME + str(len(encoded_msg)) + MSG_FRAME + encoded_msg
    
    msg = "Hello, world!"
    msg = encode_for_socketio(msg)
    ws.send(msg)
    

    【讨论】:

    • 完整示例:pastebin.com/1Xt6X4K5 - 但我并没有真正使用 HTTP,我不得不像这样修改 websocket.py:pastebin.com/rh9WxxJA 因为,我怀疑我的 urlparse 版本无法识别'ws://' 网络套接字协议。
    【解决方案3】:

    Archie1986 的回答很好,但由于 socketio 更新已经过时(更具体地说,它的协议:https://github.com/LearnBoost/socket.io-spec)...据我所知,您需要手动执行握手,然后才能请求传输(例如,websockets)连接......请注意,下面的代码不完整且不安全......首先,它忽略了握手响应中返回的支持的传输列表,并且总是试图获取一个 websocket......它还假设握手总是成功...不过,这是一个很好的起点

    import websocket, httplib
    
    ...
    
    '''
        connect to the socketio server
    
        1. perform the HTTP handshake
        2. open a websocket connection '''
    def connect(self) :
        conn  = httplib.HTTPConnection('localhost:8124')
        conn.request('POST','/socket.io/1/')
        resp  = conn.getresponse() 
        hskey = resp.read().split(':')[0]
    
        self._ws = websocket.WebSocket(
                        'ws://localhost:8124/socket.io/1/websocket/'+hskey,
                        onopen   = self._onopen,
                        onmessage = self._onmessage)
    
    ....
    

    您可能还想阅读 python-websockets:https://github.com/mtah/python-websocket

    【讨论】:

    • 这对我很有用。非常感谢您更新的答案!我希望 OP 能重新推广这个,因为实际的答案(正如你所指出的)实际上并不适用于当前的规范。我为一个运行良好的简单命令行工具填写了其余代码。它可能对其他人有用:gist.github.com/1402238 它基本上只是您的代码,还有一些非常明显的其他内容,但我希望它可以节省一些时间。
    • 截至 2019 年此答案的任何更新?
    【解决方案4】:

    写了一个:https://github.com/amitu/amitu-websocket-client/blob/master/amitu/socketio_client.py。它只支持 websockets,所以它对你可能只有边际效用。

    【讨论】:

    • 执行run() 方法时出现错误:Invalid frame - 这意味着什么?
    • Alp,这意味着库中存在错误。我已经根据各种贡献者的拉取更新了它。请随时检查最新版本,看看是否有帮助。
    • 感谢您的回复。与此同时,我切换到了 sockjs,它就像一个魅力。见stackoverflow.com/questions/10950365/…
    【解决方案5】:

    带有流行异步 Tornado Web Server 的 SocketTornad.IO 库也是可用于 python 的选项之一。

    【讨论】:

    • 或者更好的是 Tornadio2 的最新版本:github.com/mrjoes/tornadIO2 --- 但这些是服务器库,不适合用作客户端。
    【解决方案6】:

    感谢贡献者的工作,socketIO-client 库支持事件回调和通道,并且在 MIT 许可下可在 PyPI 上使用。

    带有回调的发射。

    from socketIO_client import SocketIO
    
    def on_bbb_response(*args):
        print 'on_bbb_response', args
    
    with SocketIO('localhost', 8000) as socketIO:
        socketIO.emit('bbb', {'xxx': 'yyy'}, on_bbb_response)
        socketIO.wait_for_callbacks(seconds=1)
    

    定义事件。

    from socketIO_client import SocketIO
    
    def on_aaa_response(*args):
        print 'on_aaa_response', args
    
    socketIO = SocketIO('localhost', 8000)
    socketIO.on('aaa_response', on_aaa_response)
    socketIO.emit('aaa')
    socketIO.wait(seconds=1)
    

    在命名空间中定义事件。

    from socketIO_client import SocketIO, BaseNamespace
    
    class Namespace(BaseNamespace):
    
        def on_aaa_response(self, *args):
            print 'on_aaa_response', args
            self.emit('bbb')
    
    socketIO = SocketIO('localhost', 8000)
    socketIO.define(Namespace)
    socketIO.emit('aaa')
    socketIO.wait(seconds=1)
    

    在单个套接字上定义不同的命名空间。

    from socketIO_client import SocketIO, BaseNamespace
    
    class ChatNamespace(BaseNamespace):
    
        def on_aaa_response(self, *args):
            print 'on_aaa_response', args
    
    class NewsNamespace(BaseNamespace):
    
        def on_aaa_response(self, *args):
            print 'on_aaa_response', args
    
    socketIO = SocketIO('localhost', 8000)
    chatNamespace = socketIO.define(ChatNamespace, '/chat')
    newsNamespace = socketIO.define(NewsNamespace, '/news')
    
    chatNamespace.emit('aaa')
    newsNamespace.emit('aaa')
    socketIO.wait(seconds=1)
    

    【讨论】:

    • 嘿,我们绕了一圈,看到 socketIO-client 包是从相关的 SO 问题中产生的:stackoverflow.com/questions/6692908/…
    • 我收到警告 WARNING:root:localhost:8000/socket.io [waiting for connection] ('Connection aborted.', error(111, 'Connection denied'))...可以你帮忙?
    • 你的 socket.io 服务器在运行吗?您使用的是哪个版本的 socket.io 服务器?
    • 只有一个事件有效socketIO.on('aaa_response', on_aaa_response)。如果我要添加多个事件,只有第一个有效??
    • 呃,那不好。您能否在 github 存储库上发布一个带有一些示例代码的问题,以便我们重现您的情况?
    猜你喜欢
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 2010-12-26
    • 2020-02-17
    • 2011-01-15
    • 2012-01-21
    • 2018-08-11
    • 1970-01-01
    相关资源
    最近更新 更多