Python中的Socket.IO客户端库

49 投票
6 回答
53519 浏览
提问于 2025-04-16 10:23

有没有人能推荐一个适用于Python的Socket.IO客户端库?我查了一下,发现的要么是服务器实现,要么是依赖像Twisted这样的框架。

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

仅仅使用其中一种连接方式是不够的,因为Python客户端需要能够与多个socketio服务器一起工作,而这些服务器中的很多可能不支持websockets,比如说。

6 个回答

22

socketIO-client这个库支持事件回调和频道功能,这要感谢许多贡献者的努力。它可以在PyPI上找到,并且是根据MIT许可证发布的。

发射事件并带有回调。

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)

在一个socket上定义不同的命名空间。

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)
25

首先,我不太明白为什么你的一些Socket.IO服务器不支持websockets……Socket.IO的目的是为了让前端开发人员在开发网页应用时更方便,它提供了一个抽象的接口来处理Socket.IO服务器提供的实时数据流。也许Socket.IO并不是你应用的最佳选择?不过不管怎样,我来试着回答你的问题……

目前,Python没有任何Socket.IO客户端库(gevent-socketio并不是Python的Socket.IO 客户端库……它是Python的Socket.IO 服务器库)。所以现在你需要自己写一些代码,才能直接作为客户端与Socket.IO进行连接,同时支持各种连接类型。

我知道你希望找到一个可以处理各种连接类型(比如WebSocket、长轮询等)的万能解决方案,但目前还没有这样的库。不过,我可以根据我的经验给你一些关于使用WebSocket连接类型的建议。

对于WebSocket连接类型,你需要在Python中创建一个WebSocket客户端。从命令行安装这个Python WebSocket客户端包,使用pip命令,这样它就会被添加到你的Python路径中,命令如下:

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

安装完成后,尝试以下操作,记得把SOCKET_IO_HOSTSOCKET_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)
43

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

撰写回答