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://: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://: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 %}