I'm creating a mobile app with a server backend that will authenticate a user and continuously send them updates whilst listening for post data from the mobile app. These updates will be specific to the person, pulled from a database.
From my research it seems that I should use a websocket. I'm familiar with PHP so have tried Ratchet. I've created a simple chat script with Ratchet which queries a database onMessage and sends the data to the client.
My question is, are websockets right for this? When a server receives a connection it must query the db every 5 seconds and send updated info to the app. It must listen for messages that will change the db query. Everything in Ratchet's docs seems to be focussed on subscriptions to topics rather than treating each client individually, although I've gotten around this by using:
$client = $this->clients[$from->resourceId];
$client->send("whatever_message"):
Am I complicating things by using Ratchet? Or should I use a child process to handle each client?
I am sorry for a vague questions. I've researched as best I can but cannot establish whether I'm heading in the wrong direction! Thank you for any help.
That is a good formula. Sending post data from the apps while maintaining a socket connection is a good distribution of processes. However PHP might not be your best option for running the socket server.
The reason for this is PHP is a single threaded language which doesn't sport an elegant event system.
Take NodeJs as an alternative. It too is single threaded, however you can register events on socket servers allowing the software to run additional control processes while it waits for network activity.
This does not limit you to javascript however. Work can still be delegated to PHP processes from the NodeJs application (I use NodeJs as an example only, there are other options such as Java, Python, or good ol' native).
For moving work to PHP, you can either execute commands, or use a job server to enable synchronous and asynchronous tasks.
Here are a few resources you can combine to accomplish this:
http://nodejs.org/
http://socket.io/
http://gearman.org/
http://php.net/manual/en/book.gearman.php
And if you are using Symfony:
https://github.com/mmoreram/GearmanBundle
Related
I am developing an picture sharing application with messages. Now want to know how to make it instant just like Viber or whatsapp. The timer of more than a minute is not a good idea the user will have to wait for a long time for the message to arrive. And HTTP request every second will have a lots of overload on the server.
I have heard about the socket programming but not sure if it is the best way. Also how to implement that?
So the question is What is the best way of implementing this kind of application?
I am using IOS and PHP as a server language.
There are two approaches:
You can use your own protocol over any kind of socket you want (most probably a TCP or SSL stream), and then you need a server at the other end that keeps these connections open and send notifications on the right connections when something happens (new message...). There are probably existing frameworks for this, though all I can think of right now are more geared towards integration with web applications rather than native ones. Note that this will only work as long as you app is active in the foreground. This also means you will get as many simultaneous connections to your server as there are apps running, so you may have a scalability issue.
or you can use Apple Push Notifications to send notifications to the app that there is something new happening. You may include all the relevant data in the payload, or you may trigger a connection by your app to fetch the rest of the data. This will work both in the background and the foreground, though slightly differently.
You may also mix both: use APNs when your app is in the background, and you own connection when it is in the foreground.
I'm finishing a JQuery plugin, and I need to collect usage data of some activity while the plugin is active. This data needs to be stored remotely on my servers.
However, I'm trying to find the best approach to do this. It would be similar, I guess, to how web analytics data is collected. I see two options right now and I have outlined the basic steps below.
A. AJAX -
With this approach:
I use JQuery to setup an Ajax request in my JQuery Plugin to POST data to a server
I setup this server to capture the data that was POSTED, and then use PHP to insert into a database table
B. SOCKETS -
With this approach:
I sign up for a service like PubNub
I use the PubNub Javascript SDK in my JQuery plugin to "publish" a message to a given "channel"
I set up a dedicated server or cloud server, and using SSH to login, install a web server + database + PHP, and make sure it works ok
I create my PHP script (using the PubNub PHP SDK) to "subscribe" to the pubnub "channel" my plugin will publish messages on, and then setup the mechanism to capture the data from the message and insert into a database table
I set up supervisord to daemonize my php script, and then start the daemon since I need a long-lived PHP process to run the PubNub Subscribe feature via a server.
I prefer A because it's the simplest option for me, I can use any hosted MySQL/PHP server to get it done with minimum hassle. However, I'm concerned how performant this approach would be when the plugin is being used in thousands of different web sites, or a few very busy websites, with potentially 10 - 100 database submissions per second on my remote server.
Would it make more sense to use the B approach with sockets instead, at a potentially much higher cost because of the PubNub subscription I would require to pull this off. Also, being that I don't need asynchronous connectivity as I need to make only one request per user, I'm thinking sockets might be overkill compared to the trusty ol' HTTP request directly to my server (as opposed to a message being sent through PubNub, and then to me).
What really is the best way to pull something like this off?!
Thanks in advance.
You are correct, sockets are overkill. Even Google Analytics uses HTTP requests to send data. These requests aren't required to be timely (e.g. milliseconds don't matter) so there's no reason to open a socket.
Option A for sure. Additionally check out something like AppFog if you are really worried about tons of hits to your PHP script, they offer quite a bit for free and that could take the load off of your server if it gets to be an issue.
I am building a website in PHP that handles the sessions in Redis in JSON format.
This way the session can be accessed by both the PHP interpreter and a node.js server.
What I am trying to do is now to add notifications in said website; the procedure I was thinking of is the following: (just figure it as a simple friend request to simplify it all)
user A sends friend request.
PHP uses cURL to say to node.js service to send notification
user B gets a notification because he is connected to node.js via socket.io
What are the general guidelines to achieve this? Because it looks clear to me that if user A and B are in different servers, it will be impossible to scale horizontally;
Thanks in advance.
Sounds like a you could make use of Web Sockets here with a Publication / Subscription protocol, architecture.
You get Server client functionality with web sockets.
Node is a perfect choice for a websocket server, lots of small IO.
See http://en.wikipedia.org/wiki/Web_sockets
I'm wouldn't think if the shared session is required for php - node communication, just have your clients push requests through the socket and handle the reposes as needed.
I think the approach you propose sounds quite reasonable. However, instead of doing a direct request to the service, you could consider using a message queue (zeromq, rabbitmq, whatever) which would allow you to scale it more easily as you can easily add logic to the queue processing to pass the message to the correct node instance.
I managed to get 1400 concurrent connections with socket.io on a cheap VPS with no special configuration so even with no tricks it should scale quite well. In my case most of these connections were also sending and receiving data almost constantly. It could probably have handled more than that, 1400'ish was simply the max number of users I happened to get.
Though I'd worry more about getting all those users first ;)
Use Redis's built in pub-sub capability. When the PHP server gets a request, it publishes it to a channel set up for that purpose. Each of your node servers subscribes to that channel and checks if the user involved is connected to it. If so, it sends the notification via socket.io. As a bonus, you avoid an extra network connection and your overall logic is simplified.
simply setup ur database as per required then whenever a activity is made just tell ur node js to transfer the related information through redis to php and make a process and in make a response back from php to node via channel keep checking the notification from table and show
How to make php client to client, like the chat way ? One client connects and sends something to the other client and only he recieve not all clients.
Your Question?
If I understand correctly you want one-to-one(private) messaging.
Socket Programming using PHP
You need to learn Socket programming with PHP. You could start by studying this tutorial. This has scaling problems written all over it, because PHP does not have non blocking IO, proper thread model. I advise you to just use it for fun little projects.
Non blocking IO using PHP
You could try and use PHP-MIO. I have not yet tried this, but I guess it might scale. But then again from Apache(PHP) side you will have the same problems. But when using this from both sides it could work...
long-polling(blocking IO) using PHP
P.S: got bored so I have not completely tested this ;)
Download
Below I present two solutions(prototypes) which do NOT scale. One solution uses Redis pubsub. For this you need to install(compile) redis. For this you a POSIX OS is desired, although some people have ported it to Windows. You can also use the free redistogo.com instance. The Redis solution is the prefered solution. I have put everything in an archive which you can download from here.
I also give a solution which uses named pipes. This solution does not require you to use Redis, but instead this approach needs access to the file system. I believe that this approach should also work on Windows(You have to change the filename to windows-style). I would like for somebody to try this out :). I can not test this anymore, because I have completely switched to POSIX OS(Ubuntu) a long time ago.
Requirements
At least PHP 5.3 and preferable a POSIX OS, redis.
How to use
To use both solutions you need to open two browsers(Browser A/B). I assume you are using localhost for development and that you can access files from http://localhost/6646733.
point browser A to http://localhost/6646733/redis?me=somebodyelse&to=alfred you should replace redis with pipe when trying out named pipes.
Point browser B to http://localhost/6646733/redis?me=alfred&to=somebodyelse
In browser A type a message into the textarea, which will be sent to browser B.
In browser B read the message just sent from browser A
Solutions not using PHP
The solutions below scale.
Pusher(Hosted)
With for example the hosted solution Pusher you can do chat/messaging without the scaling nightmare. Pusher even is generous to provide a free plan. But be aware that the cheap plans do NOT offer SSL so the messages can be intercepted. You should never sent private information over the wire, when not using SSL. Users/developers have provided a nice little library to use Pusher from PHP. The problem with this approach is that you are not in control, but pusher is, but then again you don't have to worry about any details.
Socket.io(open-source)
I really like socket.io, but there are off course a lot of other solutions like for example tornado. You could use Redis to efficiently communicate between PHP and the other solution(socket.io).
I don't fully understand what you are trying to do, but you can use some kind of database and have it store messages that is sent to each user, and then have your client page refresh the chat part with a AJAX kind of query to update the chat. It will then behave simular to the new Facebook chat, where all messages are stored even the ones sent in normal chat and mail. So clients can mail and chat each other at all times, when they are online it will show in their chat and when thy are offline it will show up in their inbox. But this might not be what you are trying to do.
For implementing best Chat application, use jabber server and write clients using js/flex
http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol
If it's not like chat but you want to send messages over without a server, you need both clients be server as well. A server will listen on a port for incomming connections. Write a daemon that spawns a new thread each time a client connects. Within this thread you handle the messaging.
Client A opens a connection to the server (Client B) and they can talk to each other. Or you let Client A become server and let Client B connect.
I have an existing app written in PHP (using Kohana framework) and I want to do long polling. From some things I read it seems that doing long polling with PHP is not advisable and using something like nodejs is a better choice. My question is what's the best way to integrate nodejs (or some other well suited tool for long polling) with an existing application?
For clarification my app basically is a browser plugin that you can use to send data to groups of other people. When that data is sent, I want the recipients, if they are online and also have the browser plugin, to instantly receive that data and be notified.
Possibly the best way is to let node.js listen to a port and to let PHP send messages to that port.
In Node.js you can just open a socket for listening and in PHP you can use cURL to send messages. The messages can be in JSON-format.
If the Node.js-part receives a message, it can forward it, possibly after some processing, directly to the long-polling browser.
I am creating a small hack that would allow you to do this with ease. It is in a very early stage but it has enough code for it to work: https://github.com/josebalius/NodePHP
I plan on updating the readme later today.