设想
我有一个传感器节点,它发布有关特定 MQTT 主题的信息(发送到 Mosquitto 代理)。发送的数据是纯字符串。
后端
目前我正在使用apollo-server-express
构建 GraphQL 服务器。我希望使用`graphql-mqtt-subscriptions来:
- 订阅 MQTT 代理
- 阅读特定主题的信息并将其返回到
graphiql
UI
dependencies
"dependencies": {
"apollo-server-express": "^2.8.1",
"express": "^4.17.1",
"graphql": "^14.4.2",
"graphql-mqtt-subscriptions": "^1.1.0",
"graphql-subscriptions": "^1.1.0",
"graphql-tools": "^4.0.5",
"mqtt": "^3.0.0",
"subscriptions-transport-ws": "^0.9.16"
},
代码片段
入口点server.js
代码:
import express from 'express';
import {ApolloServer } from 'apollo-server-express';
import { typeDefs } from './graphql/schema';
import { resolvers } from './graphql/resolvers';
import { createServer } from 'http';
const server = new ApolloServer({ typeDefs, resolvers});
const app = express();
server.applyMiddleware({ app });
const httpServer = createServer(app);
server.installSubscriptionHandlers(httpServer);
httpServer.listen({port: 4000}, () => {
console.log(` Server ready at http://localhost:4000/${server.graphqlPath}`)
console.log(` Subscriptions ready at ws://localhost:4000/${server.subscriptionsPath}`)
});
typeDefs
GraphQL的架构如下:
type Result {
data: String
}
type Subscription {
siteAdded(topic: String): Result
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
wheresiteAdded(topic: String)
将获取 MQTT 需要订阅的主题。例子:
subscription {
siteAdded(topic: "test/1/env") {
data
}
resolvers.js
如下所示(如可能文档中所述):
import { MQTTPubSub } from 'graphql-mqtt-subscriptions';
import { connect } from 'mqtt';
const client = connect('mqtt://my.mqtt.broker.ip.address', {
reconnectPeriod: 1000,
});
const pubsub = new MQTTPubSub({
client
});
export const resolvers: {
Subscription: {
siteAdded: {
subscribe: (_, args) => {
console.log(args.topic); // to check if this gets called or not.
pubsub.asyncIterator([args.topic]);
}
}
}
};
推理
被调用但之后console.log
出现args.topic
以下错误graphiql
:
{
"error": {
"message": "Subscription field must return Async Iterable. Received: undefined"
}
}
如果我执行return pubsub.asyncIterator()
:
它提供来自 Broker 的及时数据,但输出为null
:
{
"data": {
"siteAdded": null
}
}
我根据Apollo Docsserver.js
在上面添加了 Websockets 中间件
我在哪里出错以及如何将来自订阅主题的数据添加到graphiql
?