订阅问题:React-GraphQL Yoga Server-Apollo客户端[帮助]

时间:2019-09-17 19:41:24

标签: reactjs graphql apollo next.js subscription

我事先知道我的要求很复杂。我希望在我的应用程序中创建一个“实时聊天”系统。

我在Prisma和Apollo Client前端中使用Next.JS / graphql-yoga(服务器快递)。

我的应用程序已经很大,所以我不能太多共享它的代码,但我想知道如何使用GraphQL订阅系统。 (除了我现有的体系结构。)

我看到很多人都在使用“ subscriptions-transport-ws”和专用服务器来进行此操作。而且我找不到任何具体示例。

我的订阅解析器:

const SOMETHING_CHANGED = "something changed";

const Subscription = {
  messageSent: {
    subscribe(parent, args, ctx, info) {
      console.log("GET", ctx.pubsub);
      return ctx.pubsub.asyncIterator("post");
    }
  }
};

module.exports = Subscription;

我的CreateServer文件:

const { GraphQLServer, PubSub } = require("graphql-yoga");
const Mutation = require("./resolvers/Mutation");
const Query = require("./resolvers/Query");
const Subscription = require("./resolvers/Subscription");
const db = require("./db");

const pubsub = new PubSub();

function createServer() {
  return new GraphQLServer({
    typeDefs: "src/schema.graphql",
    resolvers: {
      Mutation,
      Query,
      Subscription
    },
    resolverValidationOptions: {
      requireResolversForResolveType: false
    },
    context: req => ({ ...req, db, pubsub })
  });
}

module.exports = createServer;

我的Index.js后端文件:

require("dotenv").config({ path: "variables.env" });
const createServer = require("./createServer");


const server = createServer();
  server.start(
    {
      cors: {
        credentials: true,
        origin: process.env.FRONTEND_URL,
      },
    },
    deets => {
      console.log(`Server : http://localhost:${deets.port}`);
    }
  );

我的变异:

  async sendMessage(parent, { from, message }, ctx, info) {
    const chat = await ctx.db.mutation.createChat({
      data: {
        from,
        message
      }
    });
    ctx.pubsub.publish("post", {
      messageSent: {
        mutation: "CREATED",
        data: chat
      }
    });
    return chat;
  }

我的查询与生成的查询相同:

chats: forwardTo("db")

我的前端页面以创建/显示消息:

import React, { Component } from "react";
import { Query, Mutation } from "react-apollo";
import gql from "graphql-tag";
import StyledForm from "../styles/StyledForm";
import Error from "../Error";

const GET_MESSAGE_QUERY = gql`
  query GET_MESSAGE_QUERY {
    chats {
      id
      from
      message
    }
  }
`;

const subscription = gql`
  subscription Message {
    messageSent {
      mutation
      data {
        id
        from
        message
      }
    }
  }
`;

const SEND_MESSSAGE_MUTATION = gql`
  mutation SEND_MESSSAGE_MUTATION($from: String!, $message: String!) {
    sendMessage(from: $from, message: $message) {
      id
      from
      message
    }
  }
`;

class MessageListView extends Component {
  componentDidMount() {
    this.props.subscribeToMore();
  }
  render() {
    const { data } = this.props;
    console.log("DATA 2 ", data);
    return (
      <ul>
        {data.chats.map(msg => (
          <li key={msg.id}> {msg.message} </li>
        ))}
      </ul>
    );
  }
}

class JoinArticle extends Component {
  // State
  state = {
    message: "",
    from: "Me"
  };
  // Handle Change
  handleChange = e => {
    const { name, value } = e.target;
    this.setState({ [name]: value });
  };

  // Render
  render() {
    return (
      <Query query={GET_MESSAGE_QUERY}>
        {({ data, loading, error, subscribeToMore }) => {
          if (loading) return <p> Chargement ...</p>;
          if (error) return <Error error={error} />;
          const more = () =>
            subscribeToMore({
              document: subscription,
              updateQuery: (prev, { subscriptionData }) => {
                if (!subscriptionData.data) return prev;
                const { mutation, data } = subscriptionData.data.messageSent;
                if (mutation !== "CREATED") return prev;
                return Object.assign({}, prev, {
                  GET_MESSAGE_QUERY: [data, ...prev.GET_MESSAGE_QUERY].slice(
                    0,
                    20
                  )
                });
              }
            });
          return (
            <>
              <MessageListView data={data} subscribeToMore={more} />;
              <Mutation
                mutation={SEND_MESSSAGE_MUTATION}
                variables={this.state}
              >
                {sendMessage => (
                  <StyledForm>
                    <fieldset>
                      <input
                        type="text"
                        value={this.state.message}
                        onChange={this.handleChange}
                        id="message"
                        name="message"
                        placeholder="message"
                        onKeyDown={async e => {
                          if (e.key === "Enter") {
                            e.preventDefault();
                            await sendMessage();
                          }
                        }}
                        required
                      />
                    </fieldset>
                  </StyledForm>
                )}
              </Mutation>
            </>
          );
        }}
      </Query>
    );
  }
}

export default JoinArticle;

如果需要更多信息,请告诉我。如果有人可以帮助我了解订阅以及如何在现有项目中实现聊天系统,则非常感谢。 <3

反应#nextjs #subscription #graphql #yogaserver #prisma #apollo

0 个答案:

没有答案