📜 ⬆️ ⬇️

Creating a blog on symfony 2.8 lts [Part 5.1]

Hi, Habr! I want to wedge a bit into the cycle of articles and show how you can easily update the list of comments in the feed in real time. How does this happen, for example, on github


To accomplish this task we will use the Post Hawk service. The code is available in the corresponding branch .

Part 1. Installing dependencies (mandatory)


If you have taken branch 5 as a basis, then you need to add a dependency to composer.json:
composer require post-hawk/hawk-api-bundle ~1.0 

and if it is 5.1, then simply
 composer update 

and wait for the install (update) package (s).
')
Next, install erlang. Builds for different systems are located here , or, if you wish, you can build from source codes .
When installing in windows, do not forget to put a tick to add the path to the PATH.

Go to any place in the file system, which one you like best (you can be close to the main project) and clone the server and client
 git clone https://github.com/postHawk/hawk_client.git git clone https://github.com/postHawk/hawk_server 

We collect rebar :
 $ git clone git://github.com/rebar/rebar.git $ cd rebar $ ./bootstrap 

The resulting file (rebar) is copied to both repositories. We need it to build the project.
The project uses version 2 rebar. Cannot run under rebar3

Go to the folder with the server, collect it and run:
 cd hawk_server nano src/hawk_server.app.src #    

 {env, [ {statistic, [{use, false}]}, user, #{ <<"login">> => <<"symblog">>, <<"domain">> => [ %       <<"127.0.0.1:8000">> ], <<"key">> => <<"very secret key">> %api .       }} ]} 

 mv .erlang .erlang_ rebar get-deps compile mv .erlang_ .erlang erl -name 'hawk_server@127.0.0.1' -boot start_sasl -setcookie test -kernel inet_dist_listen_min 9000 inet_dist_listen_max 9005 


Similarly, build and run the client:
 cd hawk_client nano src/hawk_client.app.src #  server_node, , 'test_hawk_server@127.0.0.1'  api_key (   ).   

 {env, [ {api_key, <<"very secret key">>}, {server_node, 'hawk_server@127.0.0.1'} ]} 

 mv .erlang .erlang_ ./rebar get-deps compile mv .erlang_ .erlang erl -name 'hawk_client@127.0.0.1' -boot start_sasl -setcookie test -kernel inet_dist_listen_min 9000 inet_dist_listen_max 9005 

If you want to run the process in the background, simply add the option -detached to the parameter set
For windows users, the startup utility should be changed from erl to werl

Part 2. We are finalizing the blog (mandatory for branch 5)


Bundle configuration:

 //app/AppKernel.php $bundles = array( ... new Hawk\ApiBundle\HawkApiBundle(), new FOS\JsRoutingBundle\FOSJsRoutingBundle(), ); 

 #app/config/config.yml hawk_api: client: host: '%hawk_api.client.host%' #ip   port: '%hawk_api.client.port%' #,    key: '%hawk_api.client.key%' 

 #app/config/parameters.yml parameters: hawk_api.client.host: 127.0.0.1 hawk_api.client.port: 7777 hawk_api.client.key: 'very secret key' 

 #app/config/routing.yml hawk: resource: '@HawkApiBundle/Controller/' prefix: /hawk fos_js_routing: resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml" 

Put the assets:
 php app/console assets:install --symlink web 

We finalize the controller:


 ... use Blogger\BlogBundle\Entity\Blog; use Hawk\ApiBundle\Event\GroupMessage; 

In the function of adding a comment, we place the sending of notifications:
 ... $em->persist($comment); $em->flush(); $this->sendNotification($comment, $blog); return $this->redirect($this->generateUrl('BloggerBlogBundle_blog_show', array( ... 

Well, add the function itself:

Code
 /** *      * @param Comment $comment  * @param Blog $blog  */ private function sendNotification(Comment $comment, Blog $blog) { //   $comment_text = $this->renderView('BloggerBlogBundle:Comment:index.html.twig', [ 'comments' => [$comment] ]); //  $gMessage = new GroupMessage(); $gMessage ->setFrom('comment_demon') ->setGroups(['blog_' . $blog->getId()]) ->setText(['comment' => $comment_text]) ->setEvent('new_comment') //    ; // $api = $this ->container ->get('event_dispatcher') ->dispatch(GroupMessage::NEW_MESSAGE, $gMessage) ->getResult() //HawkApi ; //       if($api->hasErrors()){ $logger = $this->get('logger'); $logger->error('Error sending message: ' . print_r($api->getErrors(), 1)); } } 


I will dwell on what is happening here. Sending messages through the service is possible in two ways. The first is as in the example above, through the symfony event system. A message object (simple or group) is created and sent with a specific type of event. The second option is to send directly using api, which can be obtained from the container:
 $api = $this->get('hawk_api.api')->getApi(); $api ->registerUser($id) ->sendMessage($from, $to, $text, $event) ->execute() ->getResult('sendMessage') ; 


We are finalizing the templates:


In src / Blogger / BlogBundle / Resources / views / Blog / show.html.twig we change the line
  <article class="blog"> 

on
  <article class="blog" data-blog-id="{{ blog.id }}"> 

as we will need a blog id to subscribe the user.

We connect scripts:
 {#src/Blogger/BlogBundle/Resources/views/layout.html.twig#} {% block javascripts %} {% javascripts '@BloggerBlogBundle/Resources/public/js/*' output='js/plugins,js' filter='?yui_js' %} <script src="{{ asset_url }}"></script> {% endjavascripts %} {% javascripts '../vendor/post-hawk/hawk-api/Resources/public/js/hawk_api.min.js' %} <script src="{{ asset_url }}"></script> {% endjavascripts %} <script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script> <script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script> {% endblock %} 


Well, write a little js


code
 $(document).ready(function () { connectToHawk(); }); function connectToHawk() { //    $.post(Routing.generate('hawk_token', { useSessionId: 1 }), {}, function (data) { if(data.errors === false){ //  HAWK_API.init({ user_id: data.result.id, token: data.result.token, url: data.result.ws, debug: true }); //    HAWK_API.bind_handler('new_comment', function(e, msg){ //   if(msg.from === 'hawk_client') return; //       //   var $comments = $('.previous-comments'), $last = $comments.find('.comment:last'), cls = 'odd', $comment = $(msg.text.comment) ; //    if($last.size()){ cls = $last.hasClass('odd') ? 'even' : 'odd'; } $comment .removeClass('odd') .addClass(cls) .hide() ; // $comments.append($comment); $comment.show('normal') }); //    HAWK_API.bind_handler('open', function(e, msg){ var id = $('.blog').data('blogId'); //     //  ,        HAWK_API.add_user_to_group(['blog_' + id]); }); } else { if(data.errors !== 'no_user') { console.error(data); } } }); } 


The first thing we do is send a request for a token to connect to the message server. Since the user is not attributed to us, then we tell the controller to use as the user id, the id of his session.
If everything is good, then we will receive in the answer: user id, connection token and server address.
Next, we initialize the connection and subscribe to events. In this case, we are interested in two of them. The first is open , arises after successfully connecting to the socket. The second is new_comment (we send it when sending a message), directly a new comment.

That's all. Thank you for attention. The code for this part is available on github in the appropriate branch.

Source: https://habr.com/ru/post/303098/


All Articles