snoke/symfony-websocket 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

snoke/symfony-websocket

最新稳定版本:v0.0.2

Composer 安装命令:

composer require snoke/symfony-websocket

包简介

README 文档

README

RFC 6455-compliant Websocket Server Bundle for Symfony 7

installation

checkout library composer req snoke/symfony-websocket

modify 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

if you do not want to use TLS:

snoke_websocket:
    context: []

note that websockets without TLS only work on localhost (tho you can still use Stunnel to wrap them into a TLS Connection)

getting started

Starting the WebSocket Server

Use the Symfony console command to start the WebSocket server

php bin/console websocket:start

You can optionally specify the IP address and port:

php bin/console websocket:start --ip=127.0.0.1 --port=9000

testing the server

you can connect and send a message to your websocket server with following command:

php bin/console websocket:test

Registering Event Listeners

to react to WebSocket events, create your own listeners.

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!");
    }
}

test again with php bin/console websocket:test

Mapping Users

the ConnectionWrapper contains getter and setter to match a connection with a 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'));
        }
    }
}

Broadcasting

you can access all connections in the Listeners through the event

foreach($event->getConnections() as $connection) {
    $connection->send($message);
}

Available Events

  • ServerStarted: Triggered when the WebSocket server is started.
  • ConnectionOpened: Triggered when a new WebSocket connection is established.
  • ConnectionClosed: Triggered when a WebSocket connection is closed.
  • Error: Triggered when an error occurs.
  • MessageReceived: Triggered when a WebSocket message is received.
  • TextFrame: Triggered after MessageReceived when a text message frame is received (WebSocketOpcode::TextFrame).
  • BinaryFrame: Triggered after MessageReceived when a binary message frame is received (WebSocketOpcode::BinaryFrame).
  • ContinuationFrame: Triggered after MessageReceived d when a continuation frame is received for a fragmented message (WebSocketOpcode::ContinuationFrame).
  • ConnectionCloseFrame: Triggered after MessageReceived when a connection close frame is received (WebSocketOpcode::ConnectionCloseFrame).
  • PingFrame: Triggered after DataReceived when a ping frame is received (WebSocketOpcode::PingFrame).
  • PongFrame: Triggered after DataReceived when a pong frame is received (WebSocketOpcode::PongFrame).

Advanced

Message Fragmentation

The server handles fragmented messages using the following opcodes:

TextFrame (0x1)
BinaryFrame (0x2)
ContinuationFrame (0x0)

When a message is fragmented:

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.

Ensure your application handles fragmented messages correctly based on RFC 6455 specifications.

统计信息

  • 总下载量: 2.06k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 7
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 7
  • Watchers: 1
  • Forks: 4
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-07-02