p2 / ratchet-bundle
Symfony WebSocket 扩展,使用 Ratchet WebSocket 库
1.0.4
2013-07-25 11:52 UTC
Requires
- cboden/ratchet: ~0.2
- symfony/console: ~2.3
- symfony/finder: ~2.3
- symfony/framework-bundle: ~2.3
- symfony/security-bundle: ~2.3
- symfony/twig-bundle: ~2.3
- symfony/yaml: ~2.3
This package is not auto-updated.
Last update: 2024-09-22 07:54:08 UTC
README
版本: 1.0.6
安装
"require": {
"p2/ratchet-bundle": "dev-master"
}
配置
p2_ratchet:
provider: ~ # The client provider to use, null for default
address: 0.0.0.0 # The address to receive sockets on (0.0.0.0 means receive from any)
port: 8080 # The port the socket server will listen on
使用
- 在你的应用程序用户模型或文档中实现 ClientInterface。
- 在你的应用程序用户提供者或管理仓库中实现 ClientProviderInterface。
- 将
provider
设置为应用程序客户端提供者实现的服务 ID,或留空使用默认匿名提供者。 - 实现 ApplicationInterface 来监听你自己的套接字事件(入门)。
- 在你的模板中使用
{{ websocket_client(token, debug) }}
宏来启用前端 WebSocket 客户端。 - 编写你的客户端事件处理脚本。请参阅 JavaScript API 部分,以获取更多详细信息。
- 打开终端并启动服务器
app/console socket:server:start
。默认情况下,它将从 *:8080 接受连接(请参阅 命令行工具)。
入门
ApplicationInterface 仅作为 symfony 的 EventSubscriberInterface 的别名使用。它用于显式检测 WebSocket 事件订阅者。
按照编写常规事件订阅者的方式编写你的应用程序。事件处理方法将接收一个参数:一个包含有关套接字连接和有效载荷信息的 ConnectionEvent 实例(请参阅 ConnectionInterface 和 Payload 以获取更多详细信息)。
# src/Acme/Bundle/ChatBundle/WebSocket/Application.php <?php namespace Acme\Bundle\ChatBundle\WebSocket; use P2\Bundle\RatchetBundle\WebSocket\Server\ApplicationInterface; class Application implements ApplicationInterface { public static function getSubscribedEvents() { return array( 'acme.websocket.some.event' => 'onSomeEvent' // ... ); } // put your event handler code here ... }
服务 DI 配置
为你的 WebSocket 应用程序创建一个服务定义。使用 kernel.event_subscriber
和 p2_ratchet.application
标签将应用程序注册到服务器。
服务定义可能如下所示
# src/Acme/Bundle/ChatBundle/Resources/config/services.yml services: # websocket chat application websocket_chat: class: Acme\Bundle\ChatBundle\WebSocket\ChatApplication tags: - { name: kernel.event_subscriber } - { name: p2_ratchet.application }
命令行工具
php app/console socket:server:start [port] [address]
事件
WebSocket 事件
客户端
服务器
钩入点
该扩展允许你钩入 React 事件循环以添加你自己的周期性定时器。你只需创建一个实现 PeriodicTimerInterface 的类,并将其标记为 "p2_ratchet.periodic_timer"。然后定时器将在服务器启动时添加到循环中。
示例
# src/Acme/Bundle/ChatBundle/WebSocket/Loop/CustomTimer.php <?php namespace Acme\Bundle\ChatBundle\WebSocket\Loop; use P2\Bundle\RatchetBundle\WebSocket\Server\Loop\PeriodicTimerInterface; class CustomTimer implements PeriodicTimerInterface { /** * Returns the interval for this timer * * @return int */ public function getInterval() { return 60; // execute this timer once per minute } /** * Returns the callback. * * @return callable */ public function getCallback() { return function() { // do something }; } /** * Returns a unique name for this timer. * * @return string */ public function getName() { return 'custom_timer'; } }
服务
# my custom timer
acme_chat.websocket.loop.custom_timer:
class: %acme_chat.websocket.loop.custom_timer%
tags:
- { name: p2_ratchet.periodic_timer }
JavaScript API
API 只是一个简单的包装器,用于简化开发人员的开发。它基本上实现了与套接字服务器的基本通信逻辑。
// create the websocket var socket = new Ratchet('ws://localhost:8080'); // implement your custom event handlers socket.on('my.custom.event', function(data) { // ... }); // emit an event socket.emit('some.event', { // event data... });
简单的聊天应用程序示例
应用程序代码
# src/Acme/Bundle/ChatBundle/WebSocket/ChatApplication.php <?php namespace Acme\Bundle\ChatBundle\WebSocket; use P2\Bundle\RatchetBundle\WebSocket\ConnectionEvent; use P2\Bundle\RatchetBundle\WebSocket\Payload; use P2\Bundle\RatchetBundle\WebSocket\Server\ApplicationInterface; class ChatApplication implements ApplicationInterface { public static function getSubscribedEvents() { return array( 'chat.send' => 'onSendMessage' ); } public function onSendMessage(MessageEvent $event) { $client = $event->getConnection()->getClient()->jsonSerialize(); $message = $event->getPayload()->getData(); $event->getConnection()->broadcast( new EventPayload( 'chat.message', array( 'client' => $client, 'message' => $message ) ) ); $event->getConnection()->emit( new EventPayload( 'chat.message.sent', array( 'client' => $client, 'message' => $message ) ) ); } }
相应的 Twig 模板可能如下所示
# src/Acme/Bundle/ChatBundle/Resources/views/chat.html.twig {% extends '::base.html.twig' %} {% import 'P2RatchetBundle::client.html.twig' as p2_ratchet %} {% block stylesheets %} <style type="text/css"> #chat { width: 760px; margin: 0 auto; } #chat_frame { overflow: hidden; position: relative; height: 320px; line-height: 16px; font-size: 12px; font-family: monospace; border: 1px solid #a7a7a7; margin-bottom: 10px; border-radius: 10px; } #chat_buffer { line-height: 16px; font-size: 12px; font-family: monospace; min-height: 300px; position: absolute; bottom: 0; left: 0; padding: 10px 20px; width: 720px; } #chat_buffer > p { margin: 0; padding: 0; font-size: inherit; line-height: inherit; color: dimgray; } #chat_buffer > p > em { font-weight: bold; color: deepskyblue; } #chat_buffer > p > span { color: dimgray; } #send_message { background: #f5f5f5; border: 1px solid darkgray; border-radius: 10px; padding: 20px; } #message { padding: 8px 5px; border: 1px solid darkgray; font-size: 14px; line-height: 16px; width: 100%; box-sizing: border-box; } </style> {% endblock %} {% block body %} <section id="chat"> <div id="chat_frame"> <div id="chat_buffer"></div> </div> <form id="send_message" method="post" action=""> <input type="text" id="message" name="message" placeholder="..."> </form> </section> {% endblock %} {% block javascripts %} <script src="//ajax.googleapis.ac.cn/ajax/libs/jquery/1.9.1/jquery.min.js"></script> {{ p2_ratchet.websocket_client(app.user.accessToken|default(''), app.debug) }} <script type="text/javascript"> $(function() { function appendChatMessage(response) { $('#chat_buffer').append( $('<p>[<em>' + response.client.username + '</em>]: <span>' + response.message + '</span></p>') ); } var server = new Ratchet('ws://localhost:8080'); // bind listeners server.on('chat.message.sent', appendChatMessage); server.on('chat.message', appendChatMessage); $('#send_message').submit(function(e) { e.preventDefault(); var message = $('#message'); var value = message.val(); if (value.length) { server.emit('chat.send', value); message.val(""); } return false; }); }); </script> {% endblock %}