You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过WebSocket连接AppSync订阅报错UnsupportedOperation求助

问题

通过WebSocket连接向AWS AppSync发送订阅请求时,收到错误:

{errorType: "UnsupportedOperation", message: "unknown not supported through the realtime channel"}

测试代码

let ws = undefined;

const id = 'XXX';
const region = 'YYY';
const apikey = 'ZZZ';

const host = id + '.appsync-api.' + region + '.amazonaws.com';
const url = 'wss://' + id + '.appsync-realtime-api.' + region + '.amazonaws.com';
const httpUrl = 'https://' + host + '/graphql';

function openWebsocket(){
  const api_header = {
    host: host,
    'x-api-key': apikey,
  };
  // payload should be an empty JSON object
  const payload = {};

  const base64_api_header = btoa(JSON.stringify(api_header));
  const base64_payload = btoa(JSON.stringify(payload));

  const appsync_url = url + '?header=' + base64_api_header + '&payload=' + base64_payload;

  return new WebSocket(appsync_url, ['graphql-ws']);
}

function runWebsocket() {
  ws = openWebsocket();

  /**
   * Send request over websocket
   * (Convenience function)
   */
  const _send = (obj) => {
    ws.send(JSON.stringify(obj));
  };

  let initializingMode = true;
  ws.onopen = (e) => {
    // initialization phase start:
    _send({ type: 'connection_init' });
  };

  ws.onmessage = (e) => {
    const data = JSON.parse(e.data);

    if (initializingMode) {
      if (data.type == 'connection_ack') {
        // Acknowledge came, so we can start subscribing

        // try to subscribe
        {
          const query = {
            query: `subscription MySubscription {
              onCreateNotifications {
                creationTime
                userid
              }
            }`,
          };
          const queryStr = JSON.stringify(query);

          _send({
            id: localStorage.getItem(HeaderItems.idToken),
            type: 'start',
            payload: {
              data: queryStr,
            },
            authorization: {
              host: host,
              'x-api-key': apikey,
            },
          });
        }

        initializingMode = false;

        return;
      }
    }


  };
  
};

问题原因及修复方案

错误点1:payload.data格式错误

AppSync的start消息要求payload.data是解析后的JSON对象,而非JSON字符串。你当前把query对象转成字符串传递,导致服务端无法正确解析查询。

错误点2:多余的authorization字段

连接建立时已经通过URL参数传递了API Key授权信息,start消息里无需重复发送authorization字段,否则会导致服务端识别错误。

错误点3:start消息的id需为唯一标识

id字段是订阅会话的唯一标识,建议使用随机字符串或UUID,避免使用可能为空或不唯一的idToken。

修正后的代码

let ws = undefined;

const id = 'XXX';
const region = 'YYY';
const apikey = 'ZZZ';

const host = id + '.appsync-api.' + region + '.amazonaws.com';
const url = 'wss://' + id + '.appsync-realtime-api.' + region + '.amazonaws.com';
const httpUrl = 'https://' + host + '/graphql';

function openWebsocket(){
  const api_header = {
    host: host,
    'x-api-key': apikey,
  };
  const payload = {};

  const base64_api_header = btoa(JSON.stringify(api_header));
  const base64_payload = btoa(JSON.stringify(payload));

  const appsync_url = url + '?header=' + base64_api_header + '&payload=' + base64_payload;

  return new WebSocket(appsync_url, ['graphql-ws']);
}

function runWebsocket() {
  ws = openWebsocket();

  const _send = (obj) => {
    ws.send(JSON.stringify(obj));
  };

  let initializingMode = true;
  ws.onopen = (e) => {
    _send({ type: 'connection_init' });
  };

  ws.onmessage = (e) => {
    const data = JSON.parse(e.data);

    if (initializingMode) {
      if (data.type === 'connection_ack') {
        // 生成唯一订阅ID
        const subscriptionId = 'sub-' + Math.random().toString(36).substring(2, 15);
        
        const query = {
          query: `subscription MySubscription {
            onCreateNotifications {
              creationTime
              userid
            }
          }`,
        };

        _send({
          id: subscriptionId,
          type: 'start',
          payload: {
            data: query, // 直接传递对象,不用转字符串
          },
          // 移除多余的authorization字段
        });

        initializingMode = false;
        return;
      }
    } else {
      // 处理订阅返回的消息
      if (data.type === 'data') {
        console.log('收到订阅数据:', data.payload.data);
      } else if (data.type === 'error') {
        console.error('订阅错误:', data.payload.errors);
      }
    }
  };

  // 处理连接错误
  ws.onerror = (error) => {
    console.error('WebSocket连接错误:', error);
  };

  // 处理连接关闭
  ws.onclose = (event) => {
    console.log('WebSocket连接关闭:', event);
  };
};

内容的提问来源于stack exchange,提问作者DarkTrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 07:15:42