V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
longzhixin
V2EX  ›  Python

Python socketIO-client 运行这段关于 socket client 的代码为甚么不会返回信息,已经困扰了好多天。

  •  1
     
  •   longzhixin · 2017-05-25 13:47:15 +08:00 · 6855 次点击
    这是一个创建于 2746 天前的主题,其中的信息可能已经有所发展或是发生改变。
    """ An example for Python Socket.io Client
        Requires: six,socketIO_client    
    """ 
    from socketIO_client import SocketIO, BaseNamespace
    import json
    import time
    import re
    import hmac
    import hashlib
    import base64
    
    import logging
    logging.getLogger('socketIO-client').setLevel(logging.DEBUG)
    logging.basicConfig()
    
    access_key = ""
    secret_key = “"
    
    def get_tonce():
            return int(time.time() * 1000000)
    
    def get_postdata():
            post_data = {}
            tonce = get_tonce()
            post_data['tonce'] = tonce
            post_data['accesskey'] = access_key
            post_data['requestmethod'] = 'post'
    
            if 'id' not in post_data:
                    post_data['id'] = tonce
    
            #modefy here to meet your requirement
            post_data['method'] = 'subscribe'
            post_data['params'] = ['order_cnybtc', 'order_cnyltc', 'account_info']
            return post_data
    
    def get_sign(pdict):
            pstring = ''
            fields = ['tonce', 'accesskey', 'requestmethod', 'id', 'method', 'params']
            for f in fields:
                    if pdict[f]:
                            if f == 'params':
                                    param_string=str(pdict[f])
                                    param_string=param_string.replace('None', '')
                                    param_string=re.sub("[\[\] ]","",param_string)
                                    param_string=re.sub("'",'',param_string)
                                    pstring+=f+'='+param_string+'&'
                            else:
                                    pstring+=f+'='+str(pdict[f])+'&'
                    else:
                            pstring+=f+'=&'
            pstring=pstring.strip('&')
            phash = hmac.new(secret_key, pstring, hashlib.sha1).hexdigest()
    
            return base64.b64encode(access_key + ':' + phash)
    
    class Namespace(BaseNamespace):
    
        def on_connect(self):
            print('[Connected]')
    
        def on_disconnect(self):
            print('[Disconnect]')
    
        def on_ticker(self, *args):
            print('ticker', args)
    
        def on_trade(self, *args):
            print('trade', args)
    
        def on_grouporder(self, *args):
            print('grouporder', args)
    
        def on_order(self, *args):
            print('order', args)
    
        def on_account_info(self, *args):
            print('account_info', args)
    
        def on_message(self, *args):
            print('message', args)
    
        def on_error(self, data):
            print(data)
    
    socketIO = SocketIO('https://websocket.btcchina.com')
    namespace = socketIO.define(Namespace)
    namespace.emit('subscribe', 'marketdata_cnybtc')
    namespace.emit('subscribe', 'marketdata_cnyltc')
    namespace.emit('subscribe', 'grouporder_cnybtc')
    namespace.emit('subscribe', 'grouporder_cnyltc')
    
    payload = get_postdata()
    arg = [json.dumps(payload), get_sign(payload)]
    namespace.emit('private', arg)
    
    socketIO.wait(seconds=1)
    namespace.disconnect()
    
    
    当我运行 namespace.emit('subscribe', 'marketdata_cnybtc')
    namespace.emit('subscribe', 'marketdata_cnyltc')
    namespace.emit('subscribe', 'grouporder_cnybtc')
    namespace.emit('subscribe', 'grouporder_cnyltc')
    这个后,发现根本没有返回东西
    
    /home/daneel/anaconda3/envs/btchina/bin/python /home/daneel/PycharmProjects/btchina/WebsocketClient.py
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [engine.io transport selected] websocket
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [engine.io heartbeat reset]
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io packet sent] 2["subscribe", "marketdata_cnybtc"]
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io packet sent] 2["subscribe", "marketdata_cnyltc"]
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io packet sent] 2["subscribe", "grouporder_cnybtc"]
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io packet sent] 2["subscribe", "grouporder_cnyltc"]
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io packet sent] 2["private", ["{\"accesskey\": \"safadfasafa\", \"id\": 1495691413689407, \"requestmethod\": \"post\", \"tonce\": 1495691413689407, \"params\": [\"order_cnybtc\", \"order_cnyltc\", \"account_info\"], \"method\": \"subscribe\"}", "fdsafdsdafdfafdasfsafasdfas="]]
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io packet received] 0
    DEBUG:socketIO-client:websocket.btcchina.com:443/socket.io [socket.io connected]
    ('message', ('0',))
    [Connected]
    [Disconnect]
    
    
    25 条回复    2017-09-04 08:30:16 +08:00
    fy
        1
    fy  
       2017-05-25 14:21:30 +08:00
    这玩意的 py 端有维护过?印象中长期处于不能用状态。
    请用 sockjs
    wwqgtxx
        2
    wwqgtxx  
       2017-05-25 14:37:41 +08:00 via iPhone
    @fy 这玩意的 py 端还一直挺好用的,只是更新缓慢却并没有什么问题
    fy
        3
    fy  
       2017-05-25 15:03:57 +08:00
    @wwqgtxx 印象中 13、14、15 这几年,一直没有使用成功过,于是就弃了。很久不关注,可能后来修了吧
    learnshare
        4
    learnshare  
       2017-05-25 15:10:16 +08:00
    之前项目里搞得 Socket.IO Python 模块貌似有问题,跟前端的版本差距很大,无法通信。
    最后写了个 Node.js 模块负责 socket <=> Socket.IO 的 proxy 了
    longzhixin
        5
    longzhixin  
    OP
       2017-05-25 15:19:58 +08:00
    ``` javascript
    // install socket.io.js for Javascript client to work
    <script src="/home/daneel/node_modules/socket.io-client/dist/socket.io.js"></script>
    <script>
    var socket = io('https://websocket.btcchina.com/');
    socket.emit('subscribe', ['marketdata_cnybtc']);
    socket.emit('subscribe', ['marketdata_cnyltc']);
    socket.on('connect', function(){
    console.log("Hello,btcc!");
    socket.on('trade', function (data) {
    console.log("Hello,trade!");
    console.log(data);});
    });
    </script>
    ```
    这段代码就可以用,在火狐浏览器打开后,console 里面会接收 socket server 的信息,但是同样用 Python 的代码就不可以,该怎么解决这个问题呢?可以用 Python 去调用上面的代码么?
    longzhixin
        6
    longzhixin  
    OP
       2017-05-25 15:22:34 +08:00
    还是希望能够指出 python 中哪个地方错了? https://github.com/invisibleroads/socketIO-client
    这个是 sockIO_client 的源码
    wwqgtxx
        7
    wwqgtxx  
       2017-05-25 19:02:38 +08:00 via iPhone
    你这里需要循环调用 socketIO.wait,只调用一次他只会处理一个请求就退出了
    kely
        8
    kely  
       2017-05-25 19:15:34 +08:00   ❤️ 1
    Wait forever.

    from socketIO_client import SocketIO

    socketIO = SocketIO('localhost', 8000)
    socketIO.wait()

    楼上+1, 请使用 socketIO.wait() 把 seconds=1 去掉
    kely
        9
    kely  
       2017-05-25 19:19:58 +08:00   ❤️ 1
    另外,请绑定 trade 事件,如:
    def on_trade_response():
    print(data)
    socketIO.on('trade', on_trade_response)
    mooncakejs
        10
    mooncakejs  
       2017-05-25 19:47:35 +08:00 via iPad   ❤️ 1
    @wwqgtxx 这个库去年到前几天还有 bug
    wwqgtxx
        11
    wwqgtxx  
       2017-05-25 21:06:30 +08:00 via iPhone   ❤️ 1
    @mooncakejs 是的,我还发过 pr,在下面有一堆人都要求作者合并,作者也一点反应都没有
    longzhixin
        12
    longzhixin  
    OP
       2017-05-25 21:17:23 +08:00
    @wwqgtxx 还是只提示这个 connect
    ![image_1bgvs0ejq1eoh6721to0rq6e089.png-45.4kB][1]


    [1]: http://static.zybuluo.com/daneel/7zkrqrjj4frno4tu5z939p5q/image_1bgvs0ejq1eoh6721to0rq6e089.png
    wwqgtxx
        13
    wwqgtxx  
       2017-05-26 00:55:52 +08:00   ❤️ 1
    我都说了,在主线程用
    while True:
    socketIO.wait()
    wwqgtxx
        14
    wwqgtxx  
       2017-05-26 01:00:46 +08:00   ❤️ 1
    换句话说 socketIO_client 在内部并没有实现事件循环,你必须单独开一个线程反复的执行 socketIO.wait()或者 socketIO.wait(timeout),否则每调用一次 wait()都只会处理一个事件,你也就只能看到 connect 事件之后程序就退出了
    longzhixin
        15
    longzhixin  
    OP
       2017-05-27 14:04:02 +08:00
    感谢, 在原先代码中加了
    while True:
    socketIO_wait()
    还是没有返回信息,麻烦再帮我下。
    ![debug]( )
    wwqgtxx
        16
    wwqgtxx  
       2017-05-27 14:34:22 +08:00 via iPhone
    ``` javascript
    // install socket.io.js for Javascript client to work
    <script src="/home/daneel/node_modules/socket.io-client/dist/socket.io.js"></script>
    <script>
    var socket = io('https://websocket.btcchina.com/');
    socket.emit('subscribe', ['marketdata_cnybtc']);
    socket.emit('subscribe', ['marketdata_cnyltc']);
    socket.on('connect', function(){
    console.log("Hello,btcc!");
    socket.on('trade', function (data) {
    console.log("Hello,trade!");
    console.log(data);});
    });
    </script>
    ```
    人家 emit 的是一个数组,你 emit 一个字符串,当然没有返回了………
    longzhixin
        17
    longzhixin  
    OP
       2017-05-27 15:24:51 +08:00
    ![改成数组依然不行啊]( )
    改成数组依然不行啊
    wwqgtxx
        18
    wwqgtxx  
       2017-05-27 17:05:21 +08:00
    才注意到,你是不是应该在 connect 上之后再 emit 呀,还没连上你 emit 给谁呀
    longzhixin
        19
    longzhixin  
    OP
       2017-05-27 17:14:02 +08:00
    @wwqgtxx 可以再给点提示么?这个代码里面没有 connect。
    wwqgtxx
        20
    wwqgtxx  
       2017-05-27 17:18:23 +08:00
    你的网页我也跑了一遍,并没有得到什么数据呀,只有最初的 connect 信息
    longzhixin
        21
    longzhixin  
    OP
       2017-05-27 17:21:01 +08:00
    @wwqgtxx 是他服务器的事情么?那段 html 昨天还能运行,然后我在 console 里面能接收数据,结果今天一试啥都不行了。你能告诉我怎么确定服务器没事么?
    longzhixin
        22
    longzhixin  
    OP
       2017-05-27 17:24:12 +08:00
    https://www.btcchina.com/apidocs/spot-exchange-market-data-websocket-api-zh.html 不同版本的代码都在这里,这是比特币中国给的 api,我按照他给的 github 代码,直接运行,就不行。我是想把这个实时数据抓下来,做一些分析。结果就卡在这第一步了。
    wwqgtxx
        23
    wwqgtxx  
       2017-05-27 17:25:03 +08:00
    也有可能是他换接口之类的了
    另外 socket.io 支持使用 http session 来做登录验证,而我这里并没有登录,你那里过了一天,可能 session 失效了,可能是必须要先登录才能拿到信息吧
    longzhixin
        24
    longzhixin  
    OP
       2017-05-27 17:28:47 +08:00
    @wwqgtxx 我们订阅的公开的市场信息,那个不需要登录。![]( )
    guyigenius
        25
    guyigenius  
       2017-09-04 08:30:16 +08:00
    楼主你好,我用比特币中国开发者平台上提供的 WebSocket 市场数据 API ( https://www.btcchina.com/apidocs/spot-exchange-market-data-websocket-api-zh.html )上面提供的 Python 版本 Socket.io 客户端示例源代码( https://github.com/BTCChina/btcchina-websocket-api-python )是可以正确运行并且获得返回结果的。我的运行环境是 Python 2.7.13 ( README.md 里面说了 compiled in python 2.7.x ),socket.io client library 使用的是 socketIO-client 0.7.2 ( https://pypi.python.org/pypi/socketIO-client/0.7.2 )。
    至于你的代码,我觉得除了 secret_key = “"这行双引号的 Typo 以外,其他地方没有什么问题,和 socketIO.wait(seconds=1)关系不大,并不是“只调用一次他只会处理一个请求就退出了”,只是运行多久的差别。我的运行结果如下:

    考虑到是三个多月前的帖子,我估计上去应该是那段时间服务器的问题,所以你肯定已经解决了问题,但是我还是回帖希望可以给你或者以后看到这贴的朋友们提供一些参考和帮助。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   905 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:26 · PVG 05:26 · LAX 13:26 · JFK 16:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.