Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subscriptionType ? #155

Open
omarsoufiane opened this issue May 18, 2017 · 7 comments
Open

subscriptionType ? #155

omarsoufiane opened this issue May 18, 2017 · 7 comments
Labels

Comments

@omarsoufiane
Copy link

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no
Version/Branch x.y.z

is there a possibility to add subscription type to the bundle or make another compatible bundle like the data loader
i think this would be possible with a library like ratchet
they already discussed the issue in webonyx
webonyx/graphql-php#9

@mcg-web
Copy link
Member

mcg-web commented May 24, 2017

webonyx/graphql-php is the best place to debate about this, the bundle is just the symfony implementation. This feature is requiring a direct implementation in the main lib... Maybe using this https://siler.leocavalcante.com/graphql/subscriptions.html could also helps...

@mcg-web
Copy link
Member

mcg-web commented May 30, 2017

feel free to reopen if needed...

@omarsoufiane
Copy link
Author

sorry for reopening this issue after a long time, i decided to implement subscription on top of your bundle, siler's example works when you create a symfony command that runs ratchet on a different port, i can pass the schema to the websocket server, however subscription resolvers need to take the payload in the function argument instead of the query variables, and i found some difficulties to add a new type of resolvers to your bundle,

@mcg-web
Copy link
Member

mcg-web commented Aug 16, 2017

@omarsoufiane can you provide some snippets of the issue please ?

@mcg-web mcg-web reopened this Aug 16, 2017
@omarsoufiane
Copy link
Author

first graphiql and react needs a higher default version on the config
and subscription types work by default
`overblog_graphql:

versions:
    graphiql: 0.9.3
    react:  15.4.2
definitions:
    schema:
        query: Query
        mutation: Mutation
        subscription: Subscription`

you need a class with a subscribe and publish method that we will register as a service to use it in the sumfony command and mutation resolver

`use GraphQL\Schema;

use Ratchet\Client;
use Ratchet\Client\WebSocket;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;

const INIT = 'init';
const INIT_SUCCESS = 'init_success';
const INIT_FAIL = 'init_fail';
const SUBSCRIPTION_START = 'subscription_start';
const SUBSCRIPTION_END = 'subscription_end';
const SUBSCRIPTION_SUCCESS = 'subscription_success';
const SUBSCRIPTION_FAIL = 'subscription_fail';
const SUBSCRIPTION_DATA = 'subscription_data';

class Subscription
{

protected $host;
protected $port;

/**
 * SubscriptionCommand constructor.
 * @param $host
 * @param $port
 */
public function __construct($host, $port)
{
    $this->host = $host;
    $this->port = $port;
}

/**
 * Returns a new websocket server bootstraped for GraphQL subscriptions.
 *
 * @param Schema $schema
 * @param array $filters
 * @param array $rootValue
 * @param array $context
 * @param int $port
 * @param string $host
 * @return IoServer
 */
function subscribe(
    Schema $schema,
    array $filters = null,
    array $rootValue = null,
    array $context = null,
    $port = 7070,
    $host = '0.0.0.0'
) {
    $manager = new SubscriptionManager($schema, $filters, $rootValue, $context);
    $server = new SubscriptionServer($manager);
    $websocket = new WsServer($server);
    $websocket->disableVersion(0);
    $http = new HttpServer($websocket);
    return IoServer::factory($http, $port, $host);
}




/**
 * Publishes the given $payload to the $subscribeName.
 *
 * @param string $subscriptionName
 * @param mixed  $payload
 */
function publish($subscriptionName, $payload = null)
{
    Client\connect('ws://127.0.0.1:7070')->then(function (WebSocket $conn) use ($subscriptionName, $payload) {
        $request = [
            'type'         => SUBSCRIPTION_DATA,
            'subscription' => $subscriptionName,
            'payload'      => $payload,
        ];
        $conn->send(json_encode($request));
        $conn->close();
    });
}

}`

then create a command that runs the websocket server on a different port

`class SubscriptionCommand extends ContainerAwareCommand
{
/**
* Configure a new Command Line
*/
protected function configure()
{
$this
->setName('graphql:subscription:server')
->setDescription('Start the notification server.')
->addOption(
'file',
null,
InputOption::VALUE_OPTIONAL,
'Path to generate schema file.'
)
->addOption(
'schema',
null,
InputOption::VALUE_OPTIONAL,
'The schema name to generate.'
)

    ;
}

protected function execute(InputInterface $input, OutputInterface $output)
{

    $output = new SymfonyStyle($input, $output);
    

    $container = $this->getContainer();

//the problem is here i guess, the schema already has resolvers and they don't accept payloads as //function argument
$schema = $container
->get('overblog_graphql.request_executor')
->getSchema();

//filters is a way to know which subscription should recieve data after you send a mutation as explained in siler
    $filters = [
        'inbox' => function ($payload, $vars) {
            return ($payload['roomid'] == $vars['roomid']) ;
        },
    ];
    $subscription = $container->get('subscription_command');
    $subscription->subscribe($schema, $filters)->run();
}

}`

@omarsoufiane
Copy link
Author

subscription server and subscription manager are two files i got from siler:
https://github.com/leocavalcante/siler/tree/master/src/Graphql

since they rely on a function specific to the framework yo need to add it

` /*
* array get function imported from sliler root
*/

public function array_get($array, $key = null, $default = null)
{
    if (is_null($key)) {
        return $array;
    }
    return array_key_exists($key, $array) ? $array[$key] : $default;
}`

@mcg-web
Copy link
Member

mcg-web commented Aug 22, 2017

thank you for the example. I don't have a lot of time to work on that right now but hope to get a look more carefully on this before the weekend...

@mcg-web mcg-web added this to the v0.12 milestone Feb 25, 2018
@mcg-web mcg-web modified the milestones: v0.12, v0.13 May 26, 2019
@mcg-web mcg-web removed this from the v0.13 milestone Dec 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants