bmoscon / cryptofeed

Cryptocurrency Exchange Websocket Data Feed Handler
Other
2.21k stars 682 forks source link

Fails to establish websocket connection in cloud deployment #1024

Closed Drake1804 closed 5 months ago

Drake1804 commented 5 months ago

Hello,

I've been using cryptofeed for my application and it runs perfectly when I execute it locally. However, when I attempt to deploy the application in a Docker container on Google Cloud Run, I encounter an issue: the subscription fails to establish a connection, resulting in a timeout error.

I've made sure to expose port 8080, but the problem persists. Could it be that additional ports need to be exposed, or might there be another configuration I'm overlooking? Any advice or suggestions you could offer would be greatly appreciated.

Thank you!

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/cryptofeed/connection_handler.py", line 59, in _create_connection
    async with self.conn.connect() as connection:
  File "/usr/local/lib/python3.10/contextlib.py", line 199, in __aenter__
    return await anext(self.gen)
  File "/usr/local/lib/python3.10/site-packages/cryptofeed/connection.py", line 104, in connect
    await self._open()
  File "/usr/local/lib/python3.10/site-packages/cryptofeed/connection.py", line 318, in _open
    self.conn = await websockets.connect(self.address, **self.ws_kwargs)
  File "/usr/local/lib/python3.10/site-packages/websockets/legacy/client.py", line 646, in __await_impl_timeout__
    async with asyncio_timeout(self.open_timeout):
  File "/usr/local/lib/python3.10/site-packages/websockets/legacy/async_timeout.py", line 169, in __aexit__
    self._do_exit(exc_type)
  File "/usr/local/lib/python3.10/site-packages/websockets/legacy/async_timeout.py", line 252, in _do_exit
    raise asyncio.TimeoutError
vincentmele commented 5 months ago

If it's truly the same code running locally and in the cloud, the specific exchange may be blacklisting the cloud provider or IP address that you may be using. I would see if I could make API calls via curl on the command line to a REST interface of the exchange to see if this is the case (lookup the API reference of the exchange to find an unauthenticated endpoint that would be appropriate for this, something like a symbol lookup may be useful).

If this works but cryptofeed still doesn't, I would then try a websocket client outside of cryptofeed to see if connections can be made.

Drake1804 commented 5 months ago

Hi @vincentmele,

Thank you so much for taking the time to reply! I've been delving deeper into the issue and found that I'm able to replicate it locally by initiating cryptofeed within a child thread. Here's a snippet of how I'm setting things up:

In the child thread:

...
def subscribe_on_feed(self)
     bf_public = BinanceFutures(config=self.config, symbols=symbols, channels=[FUNDING], callbacks={FUNDING: self.ticker}, log_message_on_error=True, timeout=120, retries=-1)
     self.feed_handler.add_feed(bf_public)
     loop = asyncio.new_event_loop()
     asyncio.set_event_loop(loop)
     self.feed_handler.run(install_signal_handlers=False)

Main thread:

ws_thread = threading.Thread(target=subscribe_on_feed)
ws_thread.start()
setup_signal_handlers(asyncio.get_event_loop())

It seems like the issue is tied to the way I'm running cryptofeed, rather than anything related to the cloud infrastructure. Could you please review the code snippet above, @vincentmele? Thank you for your assistance!

bmoscon commented 5 months ago

what uses port 8080? websockets and HTTP/S requests are going to use different ports than 8080

Drake1804 commented 5 months ago

@bmoscon you are right! Flask was on 8080. Now it works. Thank you so much!