如何在Python WebSocket客户端中添加更多头部

13 投票
2 回答
35958 浏览
提问于 2025-04-17 13:20

我正在尝试通过WebSocket连接发送会话ID(我是在与HTTP服务器进行身份验证后获得的)。我需要把它作为一个头部参数传递,这样服务器就能读取所有的头部并进行检查。

我的问题是:我该如何在现有的Python WebSocket客户端实现中添加头部?我发现没有一个可以做到这一点,或者我一开始在身份验证方面的做法就错了?

-- 更新 --,下面是我使用的代码模板:

def on_message(ws, message):
    print 'message received ..'
    print message


def on_error(ws, error):
    print 'error happened .. '
    print error


def on_close(ws):
    print "### closed ###"


def on_open(ws):
   
    print 'Opening Websocket connection to the server ... '
    
    ## This session_key I got, need to be passed over websocket header isntad of ws.send.
    ws.send(session_key)

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://localhost:9999/track",
                                on_open = on_open,
                                on_message = on_message,
                                on_error = on_error,
                                on_close = on_close, 
                                )
    ws.on_open = on_open

    ws.run_forever()

2 个回答

9

没有什么比阅读源代码更有趣的了 :))

我对Websocket客户端库的源代码进行了修改,让它可以像普通参数一样在初始化时接收一个头部信息,像这样:

ws = websocket.WebSocketApp("ws://localhost:9999/track",
                                on_open    = on_open,
                                on_message = on_message,
                                on_error   = on_error,
                                on_close   = on_close, 
                                header     = {'head1:value1','head2:value2'} 
                                )

这可以通过编辑库的websocket.py源代码中的3行来实现:

1- 添加头部参数:

   ## Line 877
   class WebSocketApp(object):
        """
        Higher level of APIs are provided.
        The interface is like JavaScript WebSocket object.
        """
        def __init__(self, url,
                     on_open = None, on_message = None, on_error = None,
                     on_close = None, keep_running = True, get_mask_key = None, header = None):

self.url = url
        self.on_open = on_open
        self.on_message = on_message
        self.on_error = on_error
        self.on_close = on_close
        self.keep_running = keep_running
        self.get_mask_key = get_mask_key
        self.sock = None
        self.header = header 

2- 然后,将self.header作为头部参数传递给websocket连接方法,像这样:

## Line 732
self.sock.connect(self.url, header = self.header) 

其实我尝试过导入WebSocketApp类,但没有成功,因为整个websocket.py模块是相互依赖的,我发现自己需要导入很多东西才能让它工作。在这种情况下,修改源代码的方法更简单、更可靠。

就这些,祝你使用修改过的库时能够顺利处理所有需要的头部信息。

14

看起来自从这个问题被提出来之后,websocket-client已经更新了,现在它可以直接接受一串字符串形式的头部参数了:

custom_protocol = "your_protocol_here"
protocol_str = "Sec-WebSocket-Protocol: " + custom_protocol
ws = websocket.WebSocketApp("ws://localhost:9999/track",
                            on_open = on_open,
                            on_message = on_message,
                            on_error = on_error,
                            on_close = on_close, 
                            header = [protocol_str]
                            )

如果你想了解所有有效的头部参数,可以查看websocket的RFC6455文档:https://www.rfc-editor.org/rfc/rfc6455#section-4.3

GitHub源码在这里:https://github.com/liris/websocket-client/blob/master/websocket.py

撰写回答