GithubHelp home page GithubHelp logo

freddie's Introduction

Application Coverage

Freddie

Freddie is a PHP implementation of the Mercure Hub Specification.

It is blazing fast, built on the shoulders of giants:

See what features are covered and what aren't (yet) here.

Installation

PHP 8.1 is required to run the hub.

As a standalone Mercure hub

composer create-project freddie/mercure-x freddie && cd freddie
bin/freddie

This will start a Freddie instance on 127.0.0.1:8080, with anonymous subscriptions enabled.

You can publish updates to the hub by generating a valid JWT signed with the !ChangeMe! key with HMAC SHA256 algorithm.

To change these values, see Security.

As a bundle of your existing Symfony application

composer req freddie/mercure-x

You can then start the hub by doing:

bin/console freddie:serve

You can override relevant env vars in your .env.local and services in your config/services.yaml as usual.

Then, you can inject Freddie\Hub\HubInterface in your services so that you can call $hub->publish($update), or listening to dispatched updates in a CLI context ๐Ÿ‘

Keep in mind this only works when using the Redis transport.

โš ๏ธ Freddie uses its own routing/authentication system (because of async / event loop).

The controllers it exposes cannot be imported in your routes.yaml, and get out of your security.yaml scope.

Usage

./bin/freddie

It will start a new Mercure hub on 127.0.0.1:8080. To change this address, use the X_LISTEN environment variable:

X_LISTEN="0.0.0.0:8000" ./bin/freddie

Security

The default JWT key is !ChangeMe! with a HS256 signature.

You can set different values by changing the environment variables (in .env.local or at the OS level): X_LISTEN, JWT_SECRET_KEY, JWT_ALGORITHM, JWT_PUBLIC_KEY and JWT_PASSPHRASE (when using RS512 or ECDSA)

Please refer to the authorization section of the Mercure specification to authenticate as a publisher and/or a subscriber.

PHP Transport (default)

By default, the hub will run as a simple event-dispatcher, in a single PHP process.

It can fit common needs for a basic usage, but using this transport prevents scalability, as opening another process won't share the same event emitter.

It's still prefectly usable as soon as :

  • You don't expect more than a few hundreds updates per second
  • Your application is served from a single server.

Redis transport

On the other hand, you can launch the hub on multiple ports and/or multiple servers with a Redis transport (as soon as they share the same Redis instance), and optionally use a load-balancer to distribute the traffic.

The official open-source version of the hub doesn't allow scaling because of concurrency restrictions on the bolt transport.

To launch the hub with the Redis transport, change the TRANSPORT_DSN environment variable:

TRANSPORT_DSN="redis://127.0.0.1:6379" ./bin/freddie

Alternatively, you can set this variable into .env.local.

Advantages and limitations

This implementation does not provide SSL nor HTTP2 termination, so you'd better put a reverse proxy in front of it.

Example Nginx configuration

upstream freddie {
    # Example with a single node
    server 127.0.0.1:8080;

    # Example with several nodes (they must share the same Redis instance)
    # 2 instances on 10.1.2.3
    server 10.1.2.3:8080;
    server 10.1.2.3:8081;

    # 2 instances on 10.1.2.4
    server 10.1.2.4:8080;
    server 10.1.2.4:8081;
}

server {
    
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com/example.com.cert;
    ssl_certificate_key /etc/ssl/certs/example.com/example.com.key;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

    location /.well-known/mercure {
        proxy_pass http://freddie;
        proxy_read_timeout 24h;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Example Caddy configuration

Single node

example.com

reverse_proxy 127.0.0.1:8080

With multiple nodes

example.com

reverse_proxy 10.1.2.3:8080 10.1.2.3:8081 10.1.2.4:8080 10.1.2.4:8081

Feature coverage

Feature Covered
JWT through Authorization header โœ…
JWT through mercureAuthorization Cookie โœ…
Allow anonymous subscribers โœ…
Alternate topics โœ…๏ธ
Private updates โœ…
URI Templates for topics โœ…
HMAC SHA256 JWT signatures โœ…
RS512 JWT signatures โœ…
Environment variables configuration โœ…
Custom message IDs โœ…
Last event ID (including earliest) โœ…๏ธ
Customizable event type โœ…๏ธ
Customizable retry directive โœ…๏ธ
CORS โŒ (configure them on your web server)
Health check endpoint โŒ (PR welcome)
Logging โŒ (PR welcome))๏ธ
Metrics โŒ (PR welcome)๏ธ
Different JWTs for subscribers / publishers โŒ (PR welcome)
Subscription API โŒ๏ธ (TODO)

Tests

This project is 100% covered with Pest tests.

composer tests:run

Contribute

If you want to improve this project, feel free to submit PRs:

  • CI will yell if you don't follow PSR-12 coding standards
  • In the case of a new feature, it must come along with tests
  • PHPStan analysis must pass at level 8

You can run the following command before committing to ensure all CI requirements are successfully met:

composer ci:check

License

GNU General Public License v3.0.

freddie's People

Contributors

bpolaszek avatar koulouklegrand avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.