WebSocketBundle icon indicating copy to clipboard operation
WebSocketBundle copied to clipboard

Difficulties to get started

Open bpolaszek opened this issue 8 years ago • 0 comments

Hello everyone,

This is not really an issue but rather a question about how to use the bundle for my use case. At first, please note I'm completely new to Websockets and maybe I have misunderstood some concepts.

TL/DR

  • How to replace ajax calls by a websocket connection to prevent browser locks, and how make the gos:websocket:server process delegate the hard work to other PHP processes with a queue system

My actual problem - using Ajax - before installing the bundle:

  • I have a Symfony app, used by several users, that allows them to get a report for tracking performance stuff, so basically just imagine a <table> with <tr>s .
  • For each row of the report, there's an active column, which could basically call {{ entity.isActive }} and render a red or a green dot.
  • However, this active state is in fact not persisted in DB, but fetched on the fly with external APIs (different partners).
  • So, for each row, an Ajax request is done to the Symfony app, which itself calls the correct API in the background, and returns a JSON with true or false. Then the browser renders a red or a green dot on the row.
  • Nevertheless, some APIs may take more than 2 seconds to reply, and sometimes more than 1 minute: some partners limit the number of requests with just a few per minute (and you guess I don't have to call only their "status" endpoint, the app makes hundreds of calls for different informations), so I have to throttle.
  • This leads to multiple opened connections to the server, that prevent my users to browse another page for minutes, since at least 1 ajax request is still pending.

How I attempted to solve this with GOSWebsocketbundle:

  • For each row, the browser subscribes to a specific channel, i.e entity/{{ entity.id }}/status
  • The gos:websocket:server process calls the corresponding API and returns the response
  • If I disable the API call and return immediately a random true or false, this works way better than the Ajax-architecture.
  • But when the external API takes too long to reply, or maybe when the process uses too much memory, the gos:websocket:server process just freezes and can't even be killed normally (using kill -9 #pid to really kill it). I have no log about that so I don't really know why it freezes. Replacing the API call with a random sleep() causes similar issues.
  • Besides, the gos:websocket:server process can handle only one "request" at once: the status requests cannot be parallelized, though they could be when using Ajax. So this solution is not better.

What I'd like to do and don't succeed:

  • For each row, the browser subscribes to a specific channel, i.e entity/{{ entity.id }}/status
  • The gos:websocket:server process queues a job (with beanstalk or whatever) and responds nothing (or OK, I'll do it), and is immediately free to accept another incoming request.
  • A worker, that means another PHP process (a Symfony command, for instance) processes the job, and publish the response to the entity/{{ entity.id }}/status channel
  • The browser got the response and renders the red or the green dot.

So my questions are:

  1. Is this schema possible ?
  2. How ? (Actually I don't figure out how the worker can have access to subscribed clients and send them messages)
  3. The app is running on Symfony 2.8, Ubuntu 14.04 with PHP 7 and already uses Beanstalk and Redis for different purposes.

Thanks a lot for your help, Ben

bpolaszek avatar Sep 14 '16 09:09 bpolaszek