使用邮递员进行 AWS Appsync 订阅 - 无协议错误

问题描述 投票:0回答:3

我正在使用 Postman 连接 AWS Appsync 订阅,如下所示:https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html

具有以下配置:

enter image description here

{“payload”:{“errors”:[{“message”:“NoProtocolError”,“errorCode”:400}]},“type”:“connection_error”}

websocket aws-appsync
3个回答
7
投票

由于缺少标头而出现问题:-

Sec-WebSocket-协议 = graphql-ws


1
投票

如果你在统一中遇到此错误,请使用这种方式;

using System.Net.WebSockets;
    
var webSocket = new ClientWebSocket();
webSocket.Options.UseDefaultCredentials = false;
webSocket.Options.AddSubProtocol("graphql-ws");

0
投票

连接 URL:确保 WebSocket 连接 URL 的格式正确。它应该采用以下格式:

wss://<your-appsync-api-id>.appsync-realtime-api.<region>.amazonaws.com/graphql

标头:连接时,需要包含适当的标头:

{
    "host": "<your-appsync-api-id>.appsync-api.<region>.amazonaws.com",
    "x-api-key": "<your-api-key>"
}

Base64 编码:标头和负载都需要进行 Base64 编码并附加到连接 URL 中:

这种创建订阅的格式对我有用,请查看:

import React, { useEffect, useState } from 'react';

const App = () => {
    const [updates, setUpdates] = useState([]);

    useEffect(() => {
        const headers = {
            "host": "<YOUR_APPSYNC_API_HOST>",
            "x-api-key": "<YOUR_API_KEY>"
        };

        const encodedHeader = btoa(JSON.stringify(headers));
        const payload = "e30="; // Base64 for {}
        const wssUrl = "wss://<YOUR_APPSYNC_REALTIME_API_ENDPOINT>/graphql";
        const connectionUrl = `${wssUrl}?header=${encodedHeader}&payload=${payload}`;

        const ws = new WebSocket(connectionUrl, "graphql-ws");

        ws.onopen = () => {
            console.log("Connected!");
            ws.send(JSON.stringify({ type: "connection_init", payload: {} }));
        };

        ws.onmessage = (event) => {
            const message = JSON.parse(event.data);
            console.log("Received:", message);

            if (message.type === 'connection_ack') {
                const subscriptionMessage = {
                    id: "1", // Unique ID for the subscription
                    type: "start",
                    payload: {
                        data: JSON.stringify({
                            query: `subscription <YOUR_SUBSCRIPTION_NAME>($variable: <VARIABLE_TYPE!>) {
                                <YOUR_SUBSCRIPTION_NAME>(<variable: $variable>) {
                                    <FIELDS_YOU_WANT>
                                }
                            }`,
                            variables: {
                                variable: "<YOUR_VARIABLE_VALUE>" // Replace with actual variable value
                            }
                        }),
                        extensions: {
                            authorization: {
                                "x-api-key": headers["x-api-key"],
                                "host": headers["host"]
                            }
                        }
                    }
                };
                ws.send(JSON.stringify(subscriptionMessage));
            } else if (message.type === 'data' && message.id === '1') {
                const update = message.payload.data.<YOUR_SUBSCRIPTION_NAME>;
                console.log("Update Received:", update);
                setUpdates(prevUpdates => [...prevUpdates, update]);
            } else if (message.type === 'ka') {
                console.log("Keep-alive received");
            }
        };

        ws.onerror = (error) => {
            console.error("Error:", error);
        };

        ws.onclose = (closeEvent) => {
            console.log("Connection closed with code:", closeEvent.code, "and message:", closeEvent.reason);
        };

        return () => {
            ws.close();
        };
    }, []);

    return (
        <div>
            <h1>WebSocket Connection</h1>
            <h2>Updates:</h2>
            <ul>
                {updates.map((update, index) => (
                    <li key={index}>
                        {/* Display your update fields here */}
                        <strong>Update:</strong> {JSON.stringify(update)} <br />
                    </li>
                ))}
            </ul>
        </div>
    );
};

export default App;

最后的笔记 Postman 限制:Postman 不适合直接测试 WebSocket 连接,因为它主要是一个 HTTP 客户端。使用专用的 WebSocket 客户端或在合适的环境(如 Create React App)中运行上述 React 代码来测试您的订阅。

错误处理:始终处理连接错误和其他事件以维护健壮的应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.