0

我正在尝试使用 Next.js 和 Dgraph 构建一个实时聊天应用程序。我找到了一个博客,他们在其中逐步解释了如何使用 React.js 来完成。我认为在 Next.js 上实现它会很容易,但我很难解决一个问题(博客网址 => https://dgraph.io/blog/post/real-time-chat-app- with-react-and-slash-graphql/)。

第一个包.json

{
  "name": "realtime-chat-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@apollo/client": "^3.0.0-rc.12",
    "@apollo/link-ws": "^2.0.0-beta.3",
    "@apollo/react-hooks": "^4.0.0",
    "graphql": "^15.5.1",
    "next": "11.0.1",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "subscriptions-transport-ws": "^0.9.16"
  },
  "devDependencies": {
    "eslint": "^7.32.0",
    "eslint-config-next": "11.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-config-standard": "^16.0.3",
    "eslint-plugin-import": "^2.24.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.4.0",
    "eslint-plugin-promise": "^5.1.0",
    "eslint-plugin-react": "^7.24.0",
    "prettier": "^2.3.2"
  }
}

第二个_App.js

我的 _app.js 文件与博客上显示的文件略有不同。我使用“动态组件”来强制客户端渲染

import dynamic from 'next/dynamic'
import { ApolloProvider } from '@apollo/client'

import '../styles/globals.css'

const apolloClient = dynamic(() => import('./../shared/apollo/ApolloSetup'), { ssr: false })

function MyApp ({ Component, pageProps }) {
  console.log(apolloClient)
  return (
    <ApolloProvider client={apolloClient}>
      <Component {...pageProps} />
    </ApolloProvider>
  )
}

export default MyApp

第三次也是最后一次

以下文件与博客上的文件完全相同,但我添加了它们以防万一。

ApolloSetup.js


import { ApolloClient } from '@apollo/client/core'
import { getMainDefinition } from '@apollo/client/utilities'
import { InMemoryCache } from '@apollo/client/cache'
import { HttpLink, split } from '@apollo/client'
import { WebSocketLink } from '@apollo/link-ws'

const endpoint = 'enpoint'

const wsLink = new WebSocketLink({
  uri: `wss://${endpoint}`,
  options: {
    reconnect: true
  }
})

const httpLink = new HttpLink({
  uri: `https://${endpoint}`
})

const link = split(
  // split based on operation type
  ({ query }) => {
    const definition = getMainDefinition(query)
    return (
      definition.kind === 'OperationDefinition' &&
            definition.operation === 'subscription'
    )
  },
  wsLink,
  httpLink
)

export default new ApolloClient({
  cache: new InMemoryCache(),
  link
})

查询.js

import { gql } from '@apollo/client'

const SUBSCRIPTION_QUERY = gql`
  subscription {
    queryMessage(order: { desc: time }) {
      name
      text
      time
    }
  }
`

const SEND_MESSAGE = gql`
  mutation sendMessage($name: String!, $text: String!, $time: DateTime!) {
    addMessage(input: [{ name: $name, text: $text, time: $time }]) {
      message {
        name
        text
        time
      }
    }
  }
`

export { SUBSCRIPTION_QUERY, SEND_MESSAGE }

Post.js

import React, { useState } from 'react'
import { useMutation, useSubscription } from '@apollo/client'
import { SUBSCRIPTION_QUERY, SEND_MESSAGE } from './../../shared/apollo/Query'

const Posts = () => {
  const [name, setName] = useState('')
  const [text, setText] = useState('')

  const [sendMessage, { error: mutationError }] = useMutation(SEND_MESSAGE)
  const { data, error: subscriptionError } = useSubscription(SUBSCRIPTION_QUERY)

  if (!data || !data.queryMessage) return (<h1>Connecting...</h1>)
  if (subscriptionError || mutationError) return (<h1>Error...</h1>)

  const handleClick = () => {
    if (name && text) {
      sendMessage({ variables: { name, text, time: (new Date()).toISOString() } })
    }
  }

  return (
    <>
      <hr></hr>
      <label>Enter you name : </label>
      <input required type="text" name="name" maxLength="25" onChange={e => setName(e.target.value)}></input>
      <label> Enter your message : </label>
      <input required type="text" name="message" onChange={e => setText(e.target.value)}></input>
      <button type="button" onClick={() => handleClick()}>Post</button>
      <hr></hr>
      <h3>Total Posts : {data.queryMessage.length}</h3>
      <hr></hr>
      <table>
        <thead>
          <tr>
            <th>Time</th>
            <th>Author</th>
            <th>Post</th>
          </tr>
        </thead>
        <tbody>
          {data.queryMessage.map((m, index) => (
            <tr key={index}>
              <td>{(new Date(m.time)).toUTCString()}</td>
              <td align="left">{m.name}</td>
              <td width="1000" align="left">{m.text}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </>
  )
}

export default Posts

运行项目时显示错误

在此处输入图像描述

我很确定那是因为 ssr 但我试图在组件上强制 csr 并且我仍然遇到同样的问题。我是使用 apollo 和 websockets 的新手,也许这是一个愚蠢的问题,但我找不到问题所在

4

0 回答 0