12

我正在尝试通过 websocket 连接(我正在使用 python websocket 客户端)发送会话 id(我在对 http 服务器进行身份验证后得到它),我需要将它作为标头参数传递,其中服务器(Tornado Websocket 服务器)将读取所有标题并检查它们。

问题是:如何添加标头以使用现有的客户端 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()
4

2 回答 2

12

自从提出这个问题以来,似乎 websocket-client 已更新为包含 websocket 标头。现在您可以简单地将标头参数列表作为字符串传递:

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

于 2013-10-09T17:37:06.773 回答
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 作为 header 参数传递给 websocket connect 方法,如下所示:

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

实际上我试图导入 WebSocketApp 类,但它没有工作,因为整个 websocket.py 模块是相互依赖的,我发现自己导入了很多东西来使它工作,猴子补丁在这种情况下更容易和更可靠.

就是这样,享受使用您需要的所有标题的修补库。

于 2013-01-23T05:37:04.897 回答