snoke / symfony-websocket

安装: 63

依赖者: 0

建议者: 0

安全性: 0

星标: 0

关注者: 1

分支: 1

开放问题: 2

类型:symfony-bundle

v0.0.2 2024-07-02 22:36 UTC

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 规范正确处理分段消息。