2016-09-29 9 views
5

Es scheint, als ob ich meinen Server gemäß der Apollo-Dokumentation unter http://dev.apollodata.com/tools/apollo-server/setup.html eingerichtet habe. In meinem Server/main.js Datei:Apollo Server mit Subscriptions-Transport-ws einrichten?

//SET UP APOLLO INCLUDING APOLLO PUBSUB 
const executableSchema = makeExecutableSchema({ 
    typeDefs: Schema, 
    resolvers: Resolvers, 
    connectors: Connectors, 
    logger: console, 
}); 

const GRAPHQL_PORT = 8080; 
const graphQLServer = express(); 

// `context` must be an object and can't be undefined when using connectors 
graphQLServer.use('/graphql', bodyParser.json(), apolloExpress({ 
    schema: executableSchema, 
    context: {}, //at least(!) an empty object 
})); 

graphQLServer.use('/graphiql', graphiqlExpress({ 
    endpointURL: '/graphql', 
})); 

graphQLServer.listen(GRAPHQL_PORT,() => console.log(
    `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql` 
)); 
//SET UP APOLLO INCLUDING APOLLO PUBSUB 

Es druckt zum Terminal log "GraphQL Server jetzt auf http://localhost:8080/graphql läuft" anzeigt, dass der Server erfolgreich initialisiert wurde.

Aber an der Spitze meiner main_layout Komponente, wenn ich diesen Code ausführen:

import { Client } from 'subscriptions-transport-ws'; 
const wsClient = new Client('ws://localhost:8080'); 

... ich diese Konsole Meldung:

WebSocket-Verbindung zu ‚ws: // localhost : 8080/'fehlgeschlagen: Verbindung wurde vor dem Empfang einer Handshake-Antwort geschlossen

Was fehlt mir?

Antwort

4

Sie müssen einen dedizierten Websocket-Server erstellen. Es wird auf einem anderen Port ausgeführt und der Code zum Einrichten wird auf dem subscriptions-transport-ws-Paket bereitgestellt.

Werfen Sie einen Blick auf den folgenden Code aus GitHunt-API Beispiel: https://github.com/apollostack/GitHunt-API/blob/master/api/index.js#L101-L134

Sie würde auch sehen, dass dieser Code auf einer Klasse abhängt SubscriptionManager genannt. Es ist eine Klasse aus einem Paket graphql-subscriptions auch von dem apollo-Team genannt wird, und Sie können ein Beispiel finden, wie es zu benutzen hier: https://github.com/apollostack/GitHunt-API/blob/master/api/subscriptions.js

+0

Der Code, den Sie markieren in GitHunt-API/api/index.js, verweist nicht auf das Schema und die Apollo docs sagen, dass das Schema muss den Server bei der Einrichtung verwiesen werden. Das Schema wird über dem markierten Code in Zeile 66 referenziert, aber das ist für einen Listener an einem anderen Port, der hauptsächlich mit der GitHub-API zu tun hat. Wäre es richtig zu sagen, dass ich den Port 3010-Code ändern muss, um Referenzen auf GitHub wegzulassen? – VikR

+0

Wenn Sie die Subskriptionen einrichten möchten (wie sie gerade sind), benötigen Sie ein Schema-Objekt, das dem SubscriptionManager-Konstruktor (auf den ich im letzten Teil meiner Antwort hingewiesen habe) gegeben wird und der dann dazu kommt aus dem Paket "subscriptions-transport-ws" an die Server-Klasse übergeben werden. Die obige Referenz bezieht sich auf den GraphQL POST-Endpunkt, der nur Mutationen und Abfragen bedient. Nach dieser Konfiguration verbleiben zwei Server an verschiedenen Ports, einer für den GraphQL-Endpunkt und einer für den Websocket, um Ereignisse an den Client zu senden. – davidyaha

+0

Ein dedizierter Websocket-Port ist nicht erforderlich - siehe meine Antwort. – antirealm

3

TL; DR: können Sie verwenden graphql-up schnell einen GraphQL-Server abruft mit Abonnements unterstützen und bereit. Hier ist ein mehr detailed tutorial auf die Verwendung in Kombination mit Apollo und dem Websocket Client subscriptions-transport-ws.

Besorgen Sie sich einen GraphQL Server mit einem Klick

Angenommen, Sie auf dieser einen Twitter-Klon basiert bauen wollen GraphQL Schema in IDL syntax:

type Tweet { 
    id: ID! 
    title: String! 
    author: User! @relation(name: "Tweets") 
} 

type User { 
    id: ID! 
    name: String! 
    tweets: [Tweet!]! @relation(name: "Tweets") 
} 

graphql-up

Klicken Sie auf diese Schaltfläche, um Ihre eigene GraphQL API zu erhalten Öffnen Sie dann den Playground, wo Sie einige Tweets hinzufügen, alle Tweets abfragen und auch Abonnements testen können.

Simple API verwenden

Lassen Sie uns zunächst einen Benutzer erstellen, die der Autor für alle kommenden Tweets sein wird.Führen Sie diese Mutation im Spielplatz:

mutation createUser { 
    createUser(name: "Tweety") { 
    id # copy this id for future mutations! 
    } 
} 

Hier ist, wie Sie alle Tweets und ihre Autoren Abfrage an Ihrem GraphQL Server gespeichert:

query allTweets { 
    allTweets { 
    id 
    title 
    createdAt 
    author { 
     id 
     name 
    } 
    } 
} 

Abonnement Unterstützung mit WebSockets

Lassen Sie uns jetzt abonnieren neue Tweets von "Tweety". Dies ist die Syntax:

subscription createdTweets { 
    Message(filter: { 
    mutation_in: [CREATED] 
    node: { 
     author: { 
     name: "Tweety" 
     } 
    } 
    }) { 
    node { 
     id 
     text 
     createdAt 
     sentBy { 
     id 
     name 
     } 
    } 
    } 
} 

nun eine neue Registerkarte im Spielplatz und eine neue Tweet erstellen:

mutation createTweet { 
    createTweet(
    title: "#GraphQL Subscriptions are awesome!" 
    authorId: "<id-from-above>" 
) { 
    id 
    } 
} 

Sie sollen ein neues Event Aufspringen in der anderen Registerkarte sehen, wo Sie zuvor abonnieren.

1

Scheint so, als würden Sie nicht wirklich den WebSocket Server machen. Verwenden Sie SubscriptionServer. Denken Sie daran, dass es absolut NICHT wahr ist, dass Sie einen dedizierten Websocket-Port haben müssen (ich dachte das auch einmal), wie davidyaha sagt. Ich habe sowohl meine normalen Abfragen als auch Subs auf dem gleichen Port.

import { createServer } from 'http'; 
import { SubscriptionServer } from 'subscriptions-transport-ws'; 
import { execute, subscribe } from 'graphql'; 
import { schema } from './my-schema'; 

// All your graphQLServer.use() etc setup goes here, MINUS the graphQLServer.listen(), 
// you'll do that with websocketServer: 

// Create WebSocket listener server 
const websocketServer = createServer(graphQLServer); 

// Bind it to port and start listening 
websocketServer.listen(3000,() => console.log(
    `Server is now running on http://localhost:3000` 
)); 

const subscriptionServer = SubscriptionServer.create(
    { 
    schema, 
    execute, 
    subscribe, 
    }, 
    { 
    server: websocketServer, 
    path: '/subscriptions', 
    }, 
);