php-binance-api
php-binance-api copied to clipboard
User Data Websocket didn't receive an update.
I placed an Order yesterday but I didn't get an update via the User Data websocket listener I had running. It had been getting updates before and had running for a couple of weeks just fine, though.
I was watching all my logs as I placed the order, but nothing came through. Normally this websocket works fine, but this one time it didn't get the update. This worries me a bit.
Has anyone else experienced this? I also have a Websocket listening ingesting the 1sec tick data - is there an issue running two sockets at the same time like this? I have them running as two separate scripts, though.
It would be nice if we could get error reporting / status about the health of the websocket in case it crashes / has issues / hears an error from the Binance API, etc...
Platform:
- linux
php version:
- 7..1.12
Thank you!
Yes I have experienced this as well. The user data websocket has been unreliable for me at times.
Do you mean the Binance side has been unreliable or do you think it has to do with the PHP side? Thanks.
I experience the same problems with their node api
Oh, interesting. Sounds like maybe the Rest API might be more reliable to get Order / Trade updates? Maybe I'll go back to using that. Do you know if there's a way to get REST updates to Orders & Trades without calling the allOrders endpoint ($api->orders()) and trades ($api->trades())? Just curious if there might be a way to get individual Order and Trade updates instead of all of them every time. Thanks.
Unfortunately, no. The REST API is more reliable but you have to request it by symbol.
I think the problem here is that the PHP Websocket does not automatically reconnect if disconnected. This needs to be fixed
Ok, thanks Jon. And thanks again for your guys' API, it is very good!
I might actually bring this up in their Telegram chat (https://t.me/binance_api_english).
I think it's a problem with my library, not with binance. I am still limited on time but I can look in to how to implement the reconnect properly.
Ok, thanks.
Hello,
I'm having the same issue on websocket to fetch balance data. As mentioned in the binance API doc, "Start a new user data stream. The stream will close after 60 minutes unless a keepalive is sent."
I'm guessing my issue is happening only after 60 minutes, I saw a keepAlive function in your lib but how to use it?
This doesn't work:
$api = new API(<KEY>,<KEY>);
$api->userData($balance_update);
$api->keepAlive();
The callback function $balance_update is never called
The keepalive should happen automatically, but I couldn't get it to work with RatchetPHP's loop structure since we already had a loop running for the websockets and you're only allowed one at a time. I'll probably need help with this. I can fix the auto-reconnect, but the keepalive logic will need some refactoring
Thanks for your answer, I understand what you mean. I'm sorry I'm not familiar enough with the project to do a PR but here's my working code to replace the "userData" WS function:
The idea is to use the loop and use Ratchet connector to have both periodicTimer and WS connection.
$loop = \React\EventLoop\Factory::create();
$loop->addPeriodicTimer(30, function () {
$listenKey = $this->listenKey;
$this->httpRequest("v1/userDataStream?listenKey={$listenKey}", "PUT", []);
});
$connector = new \Ratchet\Client\Connector($loop);
// @codeCoverageIgnoreStart
// phpunit can't cover async function
$connector($this->stream . $this->listenKey)->then(function ($ws) {
$ws->on('message', function ($data) use ($ws) {
if ($this->subscriptions['@userdata'] === false) {
//$this->subscriptions[$endpoint] = null;
$ws->close();
return; //return $ws->close();
}
$json = json_decode($data);
$type = $json->e;
if ($type === "outboundAccountInfo") {
$balances = $this->balanceHandler($json->B);
$this->info['balanceCallback']($this, $balances);
} elseif ($type === "executionReport") {
$report = $this->executionHandler($json);
if ($this->info['executionCallback']) {
$this->info['executionCallback']($this, $report);
}
}
});
$ws->on('close', function ($code = null, $reason = null) {
// WPCS: XSS OK.
echo "userData: WebSocket Connection closed! ({$code} - {$reason})" . PHP_EOL;
});
}, function ($e) {
// WPCS: XSS OK.
echo "userData: Could not connect: {$e->getMessage()}" . PHP_EOL;
});
$loop->run();
EDIT: Periodic timer is in seconds so it should be 30 * 60 instead