I have a PHP application (with Symfony2) and I need to let my users talk, and other tings, in real time (with socket.IO).
Let's focus on the chat mechanism : A logged user can talk with an other logged user (logged with FOSUserBundle in Symfony). When the user sent a message, it must be saved in MySQL and sent in real time to the other user. So the message is linked to two users (a sender and a receiver) in my MySQL database.
So I have two possibilities :
I use PHP to store messages :
I have an event on the click "submit" and call a PHP url with AJAX
If my PHP return "OK" (so he correctly added the message in database), I emit a Socket.IO event -> let doctrine deal with datas and symfony with my user
On NodeJS side, I have a listener on this event and I sent the message through Socket.IO with an other event
I use only NodeJS :
How can I log my user on PHP and NodeJS side ?
I need to use a different database for datas in real time ?
How can I share my users between NodeJS and PHP ?
I don't know what is the cleanest solution, if someone can help me.
Thanks !
Can be done using a common data store like redis to store user sessions
Check this link for reference
http://simplapi.wordpress.com/2012/04/13/php-and-node-js-session-share-redi/
Also check
http://www.slideshare.net/leeboynton/integrating-nodejs-with-php-march-2013-1
Which gives you an overview of how sessions can be shared using a common in-memory data store and some sample memcached code.
WebSockets
If you are using nodejs just for the WebSockets part, I'd suggest not to because then you'd have to replicate your user authentication logic in nodejs as well
You can instead do WebSockets in PHP using some library like http://socketo.me/
As far as storing the messages in MySQL goes
Your first approach of making an AJAX call to store the message in database, waiting for the response and then emitting a SocketIO event would lead to a sluggish chat experience.
I'd suggest you store messages to MySQL through NodeJS (asynchronously)
On a side-note check https://github.com/kyle-dorman/ChitChat.js for adding real-time chat functionality to your website.
Related
I am working on a web scraping using goutte. I am providing a list of URL from a .txt file. I have created a job which do the scraping and save the data in DB table.
I want to show the data to the user as a job gets done.
Here is a condition that I can't use ajax.
Please help me find out the solution for this. Where an event shown happened when an entry was added in DB table and also, append data in front-end table but user should never get blocked.
If you can't use ajax the only other option is push notifications, which is a better option anyway. In laravel you can do this with broadcasting. In order to use broadcasting you need another service that will use web sockets to push the notifications, because (in general) you can't use web sockets with php. Laravel supports several services for broadcasting out of the box, like pusher. Another good option is socket.io.
I want to develop real time chat with channels and these are my needs:
PHP backend to manage site
Redis as session and data primary storage
Pub/Sub to send messages only to channel's interested users
one WebSocket connection with which the messages will be send and received.
(optional) NodeJS to use great npm packages like timesync or socket.io
I see two different architectures to achieve this:
with Socket.io
with Crossbar.io
These are my questions:
Which architecture I should choose and why?
The key is the user id cannot be obtained from client, because it can be malformed. So in the first architecture I think on every socket message I should attach PHPSESSID value from cookie and on sever-side retrieve PHP session from Redis. Am I right or there is better way to get user id?
I wonder if getting user id in second architecture can be done differently?
Edit:
I choosed Crossbar.io, cause it is very powerful and allows to communicate many different language applications in real time. After studying examples, I come up with this:
On every login user have generated secret key in database.
PHP client (Thruway) connect to Crossbar server and register custom WAMP-CRA authenticator
User's browser connect to Crossbar server and is challenged. Secret and auth_id (user id) are loaded from DB with page load, so it
can accomplish challenge and send response.
PHP authenticator search in DB for user with provided secret and id equal to auth_id. If there is, then it successfully authenticate
session. Now we can trust that auth_id is real user id.
These are my question:
How I can get auth_id on subscribe?
I also added cookie authentication and browser is remembered after authentication. But when I look in Chrome DevTools there is any cookie nor value in local storage. Even after clearing cache my browser is still remember by Crossbar. I wonder how it is possible?
Edit2:
Maybe I was misunderstood, but the main question was choosing appropriate architecture and getting trusted user id. There was no attention so I awarded bounty and after that I was downvoted. I read a lot about real-time apps and finally decided to use Crossbar.io, so I edited question to be related to it. Then people started upvoting, proposing another architectures, but not really answering my questions. After all I managed to do it myself and presented my answer.
About getting user id:
Every real-time chat examples which I saw, was getting id from client. It is unsafe, because client easily can manipulate it, so I needed to find another method. After reading WAMP specs I finally figured out that I have to authenticate user not only in app, but also in Crossbar.io. I choosed the dynamic WAMP-CRA method and implemented as following:
PHP app connect to Crossbar server and register custom authenticator (similar to example)
After user login in app there is generated secret key for him and saved in database. After logout, key is destroyed.
Workflow:
Every loaded page contain user id and secret key loaded from db:
<script>
auth_id = '<?php echo $user->id ?>';
secret_key = '<?php echo $user->secret_key ?>';
</script>
User browser connect to Crossbar.io server and get response with challenge from custom authenticator.
It calculate signature using key and send along with auth_id to Crossbar.io server
Authenticator gets from DB secret for provided auth_id and calculate signature. Then signatures are compared and if they are equal then authentication is successfull.
Now auth_id contain user id and we can trust its value. Now you can refer section 'How I can get auth_id on subscribe?'.
Answers:
How I can get auth_id on subscribe?
By default publishers and subscribers does not have any knowledge about each other, but documentation show there is option to change it by configuring disclosure of caller identity. Then you can get auth_id from callback details:
PHP:
$onEvent = function ($args, $argsKw, $details, $publicationId) use ($session) {
$auth_id = $details->publisher_authid;
...
}
$session->register('com.example.event', $onEvent);
JS:
function on_event(args, kwargs, details) {
auth_id = details['publisher_authid'];
...
}
session.subscribe('com.example.event', on_event);
I also added cookie authentication and browser is remembered after authentication. But when I look in Chrome DevTools there is any cookie nor value in local storage. Even after clearing cache my browser is still remember by Crossbar. I wonder how it is possible?
First of all, clearing cache and hard reload does not remove cookies. When I was asking this question there was any cookie presented, but today I can see cbtid:
There was Chrome update two days ago, so maybe this was caused by bug in previous version.
I deeply light Streamer which is used by NASA to forward truck loads of data per second.The most reliable server for real-time messaging.
Power web, mobile, tablet, desktop, and IoT apps.
Optimized data streaming for web and mobile.
Lightstreamer enables several forms of real-time messaging. It is flexible enough to be used in any scenario, including mission critical applications.
► Real-time Data Push and Web Sockets
► In-App Messaging and Push Notifications
► Pub-sub with fan-out broadcasting and one-to-one messaging
► Firewall and proxy friendly
► Adaptive bandwidth throttling
As for your first question to get the auth_id on subscription , just monitor connection subscriptions then store tier upon successful connection.
Also cookies are not recommended , use jwt.JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.Authentication is one of the big parts of every application. Security is always something that is changing and evolving.JWT helps you solve that concern.Since it is stateless.
PHP Ratchet is one of the best implementations I've used for real-time communications via WebSockets. Its based on ZMQ Sockets which is used in several online gaming applications and chat applications.
The following examples will get you started pretty quick and will answer your questions around auth_id and subscriptions:
http://socketo.me/docs/hello-world
http://socketo.me/docs/push
Overview of the Architecture:
http://socketo.me/docs/push#networkarchitecture
I would advice creating individual connections(toppics) per conversation as it doesn't really take a hit on performance and will add an additional layer of security per chat.
I'm using websockets with pusher , PHP and some Javascript. I want display some information from my database to my client. My goal is to refresh the client when an information has insert into my database.
but am facing some problems ..
how can combine between pusher and websocket to get those data ?
how can I get data from database using websockets and a pusher for doing a real time web application that whenever i added data to the database by default they will be shown in my client page ?
In your code where you are inserting information into the database, you can also trigger an event containing that data to Pusher.
It's up to you which channel to send the event on. You could have a channel per table, or a channel per row.
Then in your browser-side JavaScript you can subscribe to any channels you wish to receive updates on. See here for documentation on how to do this.
I am helping one of my friend in his android app assignment. Here is the problem statement given in his android assignment.
Statement:- There should be proper implementation of POST method with queue to accommodate the data request even when device is in offline mode and execute data sync request from queue as soon as device is online again.
How this task could be done. Correct me if I am wrong, I am thinking that this requires to be done using SyncAdapter. If I am correct and if it has any other way then suggest the same with a tutorial link for implementation.
Yes, indeed you need to use SyncAdapter. Read more here.
Logically, you need to have a message queue, where you push new messages based on user events and possibly other events as well and you need to pop the messages from there and pass to SyncAdapter.
I have an app where basically players challenge each other. At some point their challenge completes and I need to provide them (both of them - there are two players) with an update message, like 'Hey, you won and got 100500 points'. And vice versa - "Hey You looose"
I use websockets and pusher api to tackle the live updates, this works perfectly when player is "online". But what if they are not? The way to go for me looks like I can still handle the event with pusher and instead just displaying the message, I can store it to db to table challenge_notifications with fields messages and seen = 0. it's ok, but what would be the best way then to show this to the player when he comes online next time? I don't want to have ajax request on every page load checking to see if there are any unseen notifications for the user.
I probably somehow need to fetch all pending notifications only once, when they get online?
I use Laravel 5 for my backend.
There was a recent post on the Pusher blog about how to detect if a user is online or not using the Pusher HTTP API: Enabling Smart Notifications with Pusher and SendGrid.
The example uses SendGrid, but you could instead store the update to a database, send them a Push Notification, an SMS etc.
what would be the best way then to show this to the player when he comes online next time?
I guess there are two forms of "coming online":
The user is no longer on the site and has to navigate to the site. In that case as the page loads you can query the DB and serve them up any missed notifications directly (this would seem the easiest solution). Or, if it fits your app architecture, make a single AJAX request when the page loads to get any missed notifications.
If the user has gone offline due to them being mobile or having a bad network connection. In that case you can bind to the connected event using pusher.connection.bind('connected', function() {}); and then make a query to see if they've missed any notifications.
In summary: it would seem that querying the DB for any missed notifications upon normal page render (on the server) would be the simplest solution and wouldn't required much resource usage. But there are alternative mechanisms of delivering a notifications (email, SMS) if they're not online.