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

使用k6测试Hasura GraphQL WebSocket订阅时遇id缺失错误求助

问题:Hasura GraphQL订阅测试出现"key id not present"错误

我计划使用k6对基于Hasura的GraphQL API进行订阅测试,尝试的代码如下:

import ws from "k6/ws";
import { check } from "k6";

export const myFunc = (url, access_token, id, query) => {
  const headers = {
    Authorization: access_token,
  };

  const res = ws.connect(url, { headers }, function (socket) {
    socket.on("open", function open() {
      console.log(`VU ${__VU}: connected`);

      socket.send(
        JSON.stringify({
          type: "connection_init",
          payload: headers,
        })
      );
      console.log("sending query");
      socket.send(
        JSON.stringify({
          type: "start",
          payload: {
            query: query,
            variables: {
              id,
            }
          },
        })
      );
    });
...

    socket.on("message", function (msg) {
      console.log(`VU ${__VU}: received message: ${msg}`);
      const message = JSON.parse(msg);
      if (message.type == "connection_ack")
        console.log("Connection Established with WebSocket");
      if (message.type == "data") console.log(`Message Received: ${message}`);
    });

...
};

执行后得到包含错误的日志:

INFO[0001] VU 1: connected                               source=console
INFO[0001] sending query                                 source=console
INFO[0001] VU 1: received message: {"type":"ka"}         source=console
INFO[0001] VU 1: received message: {"type":"connection_ack"}  source=console
INFO[0001] Connection Established with WebSocket         source=console
INFO[0001] VU 1: received message: {"type":"ka"}         source=console
INFO[0001] VU 1: received message: {"type":"connection_error","payload":"parsing ClientMessage failed: Error in $: When parsing the record StartMsg of type Hasura.GraphQL.Transport.WebSocket.Protocol.StartMsg the key id was not present."}  source=console

请问为何会收到“key id not present”错误?


解决方案

这个错误是因为Hasura的GraphQL WebSocket订阅协议要求**start类型的消息必须包含顶层的id字段**,这个字段是客户端生成的唯一标识符,用来区分不同的订阅会话,服务器后续的响应也会通过这个id关联对应的订阅请求。

你当前发送的start消息只包含type和payload,缺少必填的id键。修正方法很简单,给start消息添加一个唯一的id值,比如用虚拟用户ID(__VU)加时间戳生成:

// 修正后的start消息发送代码
socket.send(
  JSON.stringify({
    type: "start",
    id: `sub-${__VU}-${Date.now()}`, // 添加唯一id
    payload: {
      query: query,
      variables: {
        id,
      }
    },
  })
);

添加id字段后,Hasura就能正确解析你的订阅请求,不会再抛出"key id not present"的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:05:21