snoke / symfony-websocket
v0.0.2
2024-07-02 22:36 UTC
Requires
- php: ^8.1
- doctrine/collections: ^2.2
- psr/log: ^3.0
- react/event-loop: ^1.5
- react/socket: ^1.15
- symfony/console: ^7.1
- symfony/dependency-injection: ^7.1
- symfony/event-dispatcher: ^7.1
This package is auto-updated.
Last update: 2024-09-27 19:50:46 UTC
README
RFC 6455 兼容的 Symfony 7 Websocket 服务器组件包
安装
检出库 composer req snoke/symfony-websocket
修改 config/packages/snoke_websocket.yaml
snoke_websocket: context: tls: local_cert: 'path/to/server.pem' local_pk: 'path/to/private.key' allow_self_signed: true verify_peer: false
如果您不想使用 TLS
snoke_websocket: context: []
请注意,没有 TLS 的 WebSocket 只能在本地主机上运行(尽管您仍然可以使用 Stunnel 将它们包装成 TLS 连接)
入门指南
启动 WebSocket 服务器
使用 Symfony 命令行工具启动 WebSocket 服务器
php bin/console websocket:start
您可以指定 IP 地址和端口
php bin/console websocket:start --ip=127.0.0.1 --port=9000
测试服务器
您可以使用以下命令连接到您的 WebSocket 服务器并发送消息
php bin/console websocket:test
注册事件监听器
要响应 WebSocket 事件,创建您自己的监听器。
use Snoke\Websocket\Event\MessageReceived; use Symfony\Component\EventDispatcher\Attribute\AsEventListener; #[AsEventListener(event: MessageReceived::class, method: 'onRequestReceived')] final class MessageListener { public function onRequestReceived(MessageReceived $event): void { $connection = $event->getConnection(); $connection->send("Salutations, intergalactic sphere!"); } }
再次使用 php bin/console websocket:test
测试
映射用户
ConnectionWrapper 包含获取器和设置器,用于将连接与 Symfony UserInterface 匹配
namespace App\EventListener; use App\Security\Authenticator; use Snoke\Websocket\Event\RequestReceived; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\EventDispatcher\Attribute\AsEventListener; #[AsEventListener(event: RequestReceived::class, method: 'onRequestReceived')] final class AuthListener { public function __construct( private readonly Authenticator, private readonly SerializerInterface ) {} public function onRequestReceived(RequestReceived $event): void { $request = $event->getFrame(); $connection = $event->getConnection(); if ($request['type'] === 'auth') { $payload = $request['payload']; $user = $this->authenticator->authenticate($payload['identifier'],$payload['password']); $connection->setUser($user); $connection->send($serializer->serialize($user, 'json')); } } }
广播
您可以通过事件访问监听器中的所有连接
foreach($event->getConnections() as $connection) { $connection->send($message); }
可用事件
- ServerStarted: 当 WebSocket 服务器启动时触发。
- ConnectionOpened: 当建立新的 WebSocket 连接时触发。
- ConnectionClosed: 当 WebSocket 连接关闭时触发。
- Error: 当发生错误时触发。
- MessageReceived: 当收到 WebSocket 消息时触发。
- TextFrame: 当收到文本消息帧时在 MessageReceived 后触发 (WebSocketOpcode::TextFrame)。
- BinaryFrame: 当收到二进制消息帧时在 MessageReceived 后触发 (WebSocketOpcode::BinaryFrame)。
- ContinuationFrame: 当收到用于分段消息的续帧时在 MessageReceived 后触发 (WebSocketOpcode::ContinuationFrame)。
- ConnectionCloseFrame: 当收到连接关闭帧时在 MessageReceived 后触发 (WebSocketOpcode::ConnectionCloseFrame)。
- PingFrame: 当收到 ping 帧时在 DataReceived 后触发 (WebSocketOpcode::PingFrame)。
- PongFrame: 当收到 pong 帧时在 DataReceived 后触发 (WebSocketOpcode::PongFrame)。
高级
消息分段
服务器使用以下 opcodes 处理分段消息
TextFrame (0x1)
BinaryFrame (0x2)
ContinuationFrame (0x0)
当消息被分段时
The first frame (Text or Binary Frame) starts with FIN set to 0.
Subsequent frames (Continuation Frames) continue the message with FIN set to 0 until the last frame.
The last frame of the message has FIN set to 1, indicating the end of the fragmented message.
确保您的应用程序根据 RFC 6455 规范正确处理分段消息。