I have an app which communicate through websocket with my server. I am using Ratchet and everything works perfect. The next thing i want to implement is to make requests to some other server and push responses through websocket to clients. My question is how to make parallel requests with react. Let say i have 5 endpoints which response i want to get parallel (thread). I want to call each endpoint every .2s for example and send response to websocket server clients. For example (this is just demonstration code):
$server->loop->addPeriodicTimer(.2, function ($timer) {
curl('endpoint1');
});
$server->loop->addPeriodicTimer(.2, function ($timer) {
curl('endpoint2');
});
$server->loop->addPeriodicTimer(.2, function ($timer) {
curl('endpoint3');
});
But this timer does not work this way. Is it even possible to achive this with react?
Im am not showing websocket code because communication between clients works nice.
To start. "React (Ratchet)" - operate in one thread mode (feature libevent). That is, anything that will block the process - bad idea... Curl request - will stop work socket server until it receives a response.
For your application - I would use ZMQ.
The point is this:
you run worker process (for example: ZMQWorker),
your server sends curl-data on ZMQWorker (via ZMQ).
ZMQWorker send Curl request
after sending the request, ZMQWorker send a response to the WebSocket
(via ZMQ). It you can get via reactphp/zmq
If you need to send a lot of concurrent requests - You will need pthread library - it provides multi-threading.
I've also heard that it is possible to provide work pthread + libevent, but personally I did not do.
P.S But the use of architecture ZMQ, you get a distributed architecture, to the same scalable!
Related
I have the following scenario:
I have a WebSocket running with Ratchet (PHP WebSocket)
I use the onMessage() callback function to handle incomming data and respond accordingly.
If I get the 'start-broadcast' message via the WebSocket I have to start a loop which will send out a broadcast message to all connected clients on the WebSocket every 0.2 sec. So I need to make a loop which can do this, but I can't put it into the onMessage() function, as this will block, and I won't be able to receive any more messages via the WS.
If I get the 'stop-broadcast' message via the WebSocket I have to stop the broadcast loop.
So basically I need a way to start and stop this loop, and have this loop running parallel to the WebSocket loop so it doesn't block up.
Problems: The Socket->send() method I'm pretty sure is not thread-safe, so I need to make sure that the WS loop and my broadcast loop are not trying to send a message at the same time.
Possible approaches I have considered:
ReactPHP/Promise
Somehow use this to make an async function inside which I have a loop. I have no experience with Promise, and I don't know if it can do what I need.
Running a spearate PHP-CLI process, and use ZMQ for inter-process communication between the WS instance and the Broadcast loop.
With this I could send message back and forth from the websocket, and
I could send a message to start or stop the broadcast, also I could
send a message from the broadcast loop to the WS loop to send out a
message to the WS clients.
Using pthreads
Spawn a new Thread for the broadcast loop, this can be killed when I
want it to stop. I'm pretty sure I'll have to make sure the Socket is
only used by one thread at a time, so I'll have handle that somehow.
My question is, which approach should I take, and are there any examples or tutorials for the suggested approach?
If I get you right:
You get in a web-socket - command "start"
After receiving the request, you want to start broadcasting with 0.2
seconds interval
If you will come - command "stop", you need to stop broadcasting
Maybe I misunderstood the problem, but it's a bad idea, getting client requests start and stop brodcasting (what if everyone will send a "start command"?)
In general, I would recommend using ZMQ. This is the most scalable solution. (It is best to separate the services)
You start the server.
Waiting for commands from ZMQ, that you need to start broadcasting.
Once you get a command of ZMQ, create a timer with 0.2 second intervals and broadcasts
As soon as you get "command" stop in ZMQ - kill the timer.
OR
Your start the server ZMQ PUB and start brodcasting
Yout start web-socket
You give command start and start receive ZMQ SUB messages
You give command stop and stop receive ZMQ SUB messages
If you want a pub/sub service. Then simply create a Timer and have a list of who to broadcast. Client send "subscribe", and receive messages. Good idea use Redis for storing data between processes (WebSocket - ZMQ)
You need read ZMQ PHP DOC, before using ZMQ and see reactphp/zmq lib
I'm really struggling to understand the way PHP asynchronous requests work. It seems to me that there cannot be any true asynchronous behaviour in PHP because to receive a response from an asynchronous request, you have to delay execution of the script (blocking, essentially) which then defeats the purpose.. right?
What I'm trying to do from a page on my site is:
Initiate AJAX request to (local) controller to begin the remote API
requests
Use a loop of GuzzleHTTP requests to remote API
Upon completion of each request, send the result to a socket.io server which then emits a message back to the listening client (the original page that initiated the AJAX request)
Now, I have this working - with one caveat: the GuzzleHTTP requests are not asynchronous and the remote API is very slow (usually takes around 10 seconds to receive the JSON response) so when there are 10 tasks, my connection to the server is frozen for over a minute. Opening new tabs/windows and trying to access the site results in waiting until the original script run has completed.
This seems to indicate that I misunderstood how HTTP requests work. I thought that each individual browser window (or request) was completely separate as far as the server is concerned but from the result I'm seeing, perhaps this is not exactly the case?
This is why I started looking into asynchronous requests and discovered that they don't really seem all that.. asynchronous.
So what I'm really looking for is help filling the gaps/misunderstandings in my knowledge of:
Why the blocking occurs in the first place (in terms of new, completely separate requests)
Where I might look to implement a solution.
I want to create a web application where the UI updates in real time (or as close to real time as you're going to get). Data for the UI comes from the server.
I don't want to use traditional HTTP requests where I constantly send requests to the server for new data. I'd rather have a connection open, and have the server push data to the client.
I believe this the publisher/subscriber pattern.
I've heard people mention zeromq, and React and to use Websockets. But from all the examples I've looked at I can't really find anything on this. For example zeromq has examples that show server and client. Do I implement the server, and then use websockets on the UI end as the client?
How would something like this be implemented?
Traditional HTTP Requests is still what all of this is all about still.
You can have Regular HTTP Requests:
- Users sends Request to Server
- Server responds to said request
There's also Ajax Polling and Ajax Long Polling, the concept is similar.
Ajax Polling means, an HTTP request is sent every X seconds to to look for new information.
Example: Fetch new Comments for a section.
Ajax Long Polling is similar, but when you send a request to the server, if there are no responses ready to give to the client, you let the connection hang (for a defined period of time).
If during that time new information comes in, you are already waiting for it. Otherwise after the time expires, the process restarts. Instead of going back and forth, you send a request - wait, wait - and whether you receive a response or not, after a period of time, you restart the process.
WebSockets is still an HTTP Request.
It consists in the client handling the weight in front-end, by opening WebSocket request to a destination.
This connection will not close - and it will receive and send real-time information back and forth.
Specific actions and replies from the server, need to be programmed and have callbacks in the client side for things to happen.
With WebSockets you can receive and transmit in realtime, it's a duplex bi-directional connection.
So yes, in case it wasn't clear.
You setup a WebSocket Server, running on a loop, waiting for connections.
When it receives one, there's a chat-like communication between that said server and the client; the client who needs to have programmed callbacks for the server responses.
First of all, I am completely new on many stuff, so I will welcome any inputs, including suggestions, existing projects, existing models, etc.
My current problems are:
The background service maintains a queue of tasks. The background service is written in C++ or python.
When a client clicks "Create Task" button in browser, the information will be sent to web server and the web server script (written in PHP) will initiate an RPC call to the background service to append the task to the internal queue.
The client browser will initiate an AJAX request to wait for the completion of the task. The AJAX request will hold until the task is completed (or failed) or the client cancels the request.
Thus, I need an low cost way to get the task progress which is run on a background service process.
I can think of two ways:
The background service can inform the server AJAX script about the progress pro-actively. This is low cost but I actually do not know how to do it. Does any RPC framework provides such asynchronous call back? Currently the RPC framework I decided to use is Thrift because of its multi-languages support.
The AJAX script on server side will make an RPC call to get current progress every a few seconds, and sleep in between. Upon completion, the AJAX script will return, otherwise it will just let the client browser wait by not returning. This is actually simpler but I am not sure about its cost. Note that delay isn't an issue to me here because I suppose that the clients are okay to wait for a few more seconds.
Is there any common way/model to deal with this problem?
Thanks for the help.
Depends on how you code it. The common way to do it is to make a javascripted ajax request every 1-3 seconds or so and poll the progress from the server.
This will intermediately close the connection and be more gentle to the server. If you use a persistent connection (WebSockets also fall into this category), you will keep the server busy. Besides, a "sleep" keeps the CPU busy - which is something I would try to avoid if I were you. On the other hand, if you've got the resources for that...
I can only repeat myself: it depends on how you code it and what you expect of it in the end.
If you want the client do some more work and treat the server gentle, choose your 1st option and if you think your server can handle it, choose the 2nd option and go "persistent" and even use WebSockets (which represent persistent connections to your server - remember that they aren't widely supported by web-browsing clients yet either).
Although I think that in the end - the trade-off of a simple progress compared to hogging your server CPU with constant sleeps and some persistent connections on-top of that will make you choose your 1st option: poll the server script for the progress value every x secs from the client side. Btw.: it's what Twitter does and their servers survived until today! ;)
I think, You can use WebSockets for that.
You can use WebSockets.
Establish a WebSockets connection between the client and a web service that has access to the information you need to pass to the client.
With web sockets, you don't need to poll the server asking it for progress, but rather have the server notify the client whenever it's ready.
A backwards compatible implementation would be long polling.
Cheers
How can I write a real time chat using XAJAX and PHP?
In other words, is there a way to send xajax responses from the server to multiple clients?
Or is the only possibility to check for new messages every few seconds on client side?
No. Clients must "poll" the server repeatadly.
I think the key here is to think interaction design. The trick is to fool the user into thinking that the chat is instant, but when in reality it updates once every 1 or 2 or 3 or 10 seconds.
Ideas:
1) When the user sends a message, show it directly in the chat and trigger a poll.
2) If a poll comes back with multiple messages from other users, don't add them all at once, actually add them over a period of 1-2 sec or so, with random spacing, making it look like they're coming in "instantly" and independently. (If a bunch of messages come in at once the user is very quick to realize that the chat updated there and then, and not continiously.)
3) If the user is idle for x amount of time. Drop the poll rate to once every 10sec or so.
4) If the user is active, ie sending a lot of messages, poll more often.
5) Have a static file for every channel that your write the time the chat last updated to. For instance file chat-teenfun-lastupdate.txt has the contents 1224934239 or whatever time format you prefer. Serve this file statically and let clients poll this file in order to check if the channel has updated, rather that calling chat-poll.php?ch=teenfun that does a dynamic check. Static files are served around 10-100 times faster, depending on the work involved for the dynamic script, and you're gonna need it when you get 250+ users polling.
Good luck and have fun!
/0
PS. Alternatively you could actually let clients do an ajax call to the server and keep them 'hanging'. That is you accept their request and pretend to start sending data back, but then you just pause. When something happends you finish the response with the approriate data. For this to work I believe you'd need to write your own HTTP-server though, that does this specifically, as you can't have 250 php processes hanging around in memory. Maybe Lighttpd could be used in this way somehow with that LUA cache mod. I don't know. Would be interesting though. Hell I gotta try it sometime :)
Sure there is, but I don't think it'll be very efficient with many users. You can either do polling where each client polls the server to see if there are any new messages, or you could use the comet technique in which the server can push new messages to the clients - Check out the Comet plugin for XAJAX. How this would be implemented using XAJAX and PHP is beyond me, but here's how I would try to implement it.
Let each client connect to the server (login etc), then:
For each message sent by a client (sender) update the message queue for client (receiver)
Let client poll server for new messages in the queue / Push the new messages via comet.
Update GUI if there are new messages.
Rinse, lather, repeat
Using a true IM server like ejabberd could go a long way, be more efficient and allow your users to connect via desktop clients (if that's what you want). I'd probably use that as a backend, IOW ejabberd would be the server and PHP would be the client using XMPP in PHP, and act as a proxy for the webgui.
See also:
Google Techtalk on Gmail's chat feature (and scalability issues)
That's my $0.02
As long as there there is not HTTP push technology you will never get a realtime chat only using JavaScript.
Possible workarrounds:
use a Flash Movie or a Java Applet to perform some socket communication
hold polling requests back on the server side for a few seconds
You could use websockets, but being a new HTML5 feature it's kinda limited. Lucky for you there is socksjs, which implements websockets on browsers that do not handle it.
On the hosting side you should be able to use any websockets server, there's a few for PHP.
If you are looking to implement a chat server written with a scripting language such as PHP/JSP, technique of hanging HTTP connection will have to be ticked off from your your options list. The reason is most of the web severs (specially shared hosts) don't like too many connections hanging.
You can find everything you need to implement a web client and PHP chat server in this "Optimized Chat Server Protocol for Server Side Scripting Languages" publication.
The best strategy I've seen is to do an AJAX request for messages and then restart that exact same request as soon as it finishes.
On the server side, make the script "stall" for 60 seconds or until a new message is received. This keeps the same connection open for a max of 60 seconds, but when a new message is received, it outputs it and stops immediately, prompting the client-side AJAX to open another connection.
This provides almost instant notification of new messages and is also much easier on the server than making a new connection every x seconds.