WebSocketBundle
WebSocketBundle copied to clipboard
Difficulties to get started
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:
- Is this schema possible ?
- How ? (Actually I don't figure out how the worker can have access to subscribed clients and send them messages)
- 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