JDare / ClankBundle

A Symfony2 Bundle for use with Ratchet WebSocket Server
MIT License
131 stars 31 forks source link

More documentation on "practical usage" #39

Open gittix09 opened 9 years ago

gittix09 commented 9 years ago

I'm trying to build a chat app on a website (private use only... just for learning purposes). However, after reading the bundle documentation (which is great) I found myself with many questions. Please refer to this StackOverflow question: http://stackoverflow.com/questions/28937843/symfon2-clankbundle-simple-private-and-group-chat-database-shcema-and-logi

jjsaunier commented 9 years ago

Your feedback on "first hand usage" is very interesting. I took over the development of my side because it is not actively maintained (https://github.com/GeniusesOfSymfony/WebSocketBundle). And I have planed to improve the docs and your questions help to know what is must be improved :)

So, for your first question "What database schema would you suggest?" for your example 2 tables chat_messages and chat_room are enought where chat_message have many to one relationship to chat_room

chat_room:
 name (human friendly, name of room)
 canonical_name (system friendly, like a DSN)

chat_message:
 user_id (fk 1 - n)
 room_id (fk 1 - n)
 created_at (datetime)
 internal (bool, sended by internal bot ?, for your case it may be useless) 
 centent (textaera or varchar, content of your message) 

This is a very simple schema, adapt according to your needs ofc.

Second question How would I manage the "topics"? and also "how do I manage the name of the channel " :

In clank approach, you register a topic against a channel definition.

e.g :

Some channels definitions:

To handle chat/room-81111, chat/room-12235 channels, you must register your topic name as "chat" To handle chat2/room-25653 you must register your topic name as chat2 To handle chat3/room-14565 you must register your topic name as chat3

If your channel is dynamic, don't worries, chat/* will be catch by topic named "chat", so chat2/* by topic named chat2 etc ...

To manage users inside topic, you must refer at https://github.com/JDare/ClankBundle/blob/master/Resources/docs/SessionSetup.md ratchet will use cookie/session to auth your via the cookie to retrieve the user session.

Here the full example of how auth the user against symfony app https://github.com/GeniusesOfSymfony/WebSocketBundle/blob/master/Event/ClientEventListener.php#L60, my fork provide full built-in auth.

How secure this, I will not say "How" because that depend of your system, so if you use ACL, RBAC, or just simple security role provided by symfony, I think you mean "where". In onSubscribe, check your user have access to the topic $topic->getId() you can easily check by exploding via '/' and check the second argument (who is the chat room id).

If you don't have any permissions system and symfony ACL is familiar to you, you can swiftly implement ACL where room entity is the OID and the connected user is the SID. And looks like $securityContext->isGranted(['VIEW, 'EDIT'], $roomEntity)

If you want your own simple system (I think it's more simple for your use case), you can create a third table like "chat_user_room_permission" where you list wich user can access on what channel.

gittix09 commented 9 years ago

Hello!! I'm very glad you answered this question. Thank you very much!! I think GosWebsocketBundle is a great resource for professional developers and amateurs like me. The information you provided was very useful, and I feel I'm getting closer to understand how to use this bundle in 'real-life' projects. I'm very confident that the WebSocketBundle could be even more popular if 2 step-by-step tutorials were added to the documentation. I'll be glad to help you (for example I can create a screencast/video-tutorial to demostrate how to install/configure and launch the application). Let me explain.

STARTING POINT (so that everyone can start in the same conditions): Symfony Standard Edition + FOSUserBundle -- This will provide easy user authentication --

TUTORIAL N°1: Basic live chat between logged-in online friends (messages are NOT saved to database) Please note the three keywords "logged-in", "online" and "friends".

When the user logs in and goes to the chat page (app_dev.php/mychat), he will see a list of all his friends who are currently online (and logged-in of course). By clicking on the name of ONE of his friends, the user will be able to chat with him/her; it will be a private conversation (= only the two users will receive the messages). Think of Whatsup/Fb Messanger between two people (but without saving messages in the database).

Side-notes: A) For the sake of this tutorial I would suggest to use a simple "friendship" table. id | user1_id | user2_id For each friendship between 2 users, there will be 2 records. Example: if John (id= 16) is a friend of Mark (id = 17): 1 | 16 | 17 2 | 17 | 16

B) For the layout, I would suggest to use a simple 2 colums bootstrap layout. Left column = list of friends online Right column = chat content + text input + send button

TUTORIAL N°2: Mysql table to save all messages. Please first of all look at this layout... it's the best explanation. You will understand immediately. http://revox.io/webarch/2.7/user-profile.html CLICK on the user icon (top right of the page) to open the chat. It's just a layout with no actual functionality but it's really great. Basicly it's the same as Facebook or Whatsup.

The difficult part here is that when the user logs-in, he/she needs to see a list of his/her most recent discussions in a chronological desc order. So:

Here is an example with 2 discussions:
John | Mark discussion (John) 9:00 How are you? (Mark) 12:00 Fine

John | Jane discussion (John) 10:00 Hello!!

As you can see, even if John sent his last message at 10:00 to Jane, John's most recent discussion is that with Mark because Mark wrote back at 12:00.


What do you think of this idea? As I said earlier, I would be glad to provide feedback if you would like to create these two tutorials. The documentation about each part of the bundle is good... it teaches the reader how to use each function.... but the diffiicult part is how to "merge" it all together in a 'real-life' project.

jjsaunier commented 9 years ago

Happy to see that helped you.

Today GosWebSocketBundle is not popular because it's the first time I speak about him on "public place", he is currently under dev, and need a pubsub router component (who is under dev and will be released soon as possible)

Today I have one open source bundle on top of websocket bundle, it's https://github.com/GeniusesOfSymfony/NotificationBundle (Real time notification) and incubator project is here https://github.com/ProPheT777/real_time_bidirectional_notification-symfony2-redis-websocket-pubsub.

Chat application is definitely the first apps who people think to build on top of websocket, it's good idea, and very simple to create.

But before start tutorial application, I must finish :

Currently my focus is on PubSubRouterBundle, because I really need to implement it on NotificationBundle, and that will improve topic/rpc handling in WebsocketBundle.

I need to finish the professional project who is behind these open sourced bundles :)

Only after that I will can spend more time to create real use case.

gittix09 commented 9 years ago

Great!! I'll be waiting ;)