Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.Net中使用GraphQL客户端库实现AWS Appsync_C#_.net_Websocket_Graphql_Aws Appsync - Fatal编程技术网

C# 在.Net中使用GraphQL客户端库实现AWS Appsync

C# 在.Net中使用GraphQL客户端库实现AWS Appsync,c#,.net,websocket,graphql,aws-appsync,C#,.net,Websocket,Graphql,Aws Appsync,我正在尝试在.net中实现一个类似于此python示例的应用程序同步订阅 我使用nuget包GraphQL.Client启动了这个程序 查询/变异的执行工作正常,如 但订阅不起作用 使用GraphQL.Client的我的代码: using var graphQLClient = new GraphQLHttpClient("https://<MY-API-PATH>.appsync-realtime-api.<AWS-region>.amazonaws.com/graph

我正在尝试在.net中实现一个类似于此python示例的应用程序同步订阅

我使用nuget包GraphQL.Client启动了这个程序 查询/变异的执行工作正常,如 但订阅不起作用

使用GraphQL.Client的我的代码:

using var graphQLClient = new GraphQLHttpClient("https://<MY-API-PATH>.appsync-realtime-api.<AWS-region>.amazonaws.com/graphql", new NewtonsoftJsonSerializer());

 graphQLClient.HttpClient.DefaultRequestHeaders.Add("host", "<API HOST without https or absolute path and 'realtime-' text in the api address>"); //As given in the python example

graphQLClient.HttpClient.DefaultRequestHeaders.Add("x-api-key", "<API KEY>");
var req= new GraphQLRequest
{
    Query = @"subscription SubscribeToEventComments{ subscribeToEventComments(eventId: 'test'){  content }}",
    Variables = new{}
};

IObservable<GraphQLResponse<Response>> subscriptionStream = graphQLClient.CreateSubscriptionStream<Response>(req, (Exception ex) =>
{
      Console.WriteLine("Error: {0}", ex.ToString());
});

var subscription = subscriptionStream.Subscribe(response =>
{
                Console.WriteLine($"Response'{Newtonsoft.Json.JsonConvert.SerializeObject(response)}' ");
},
ex =>
{
Console.WriteLine("Error{0}", ex.ToString());
});
static public async Task CallWebsocket()
        {
            try
            {
                _client = new ClientWebSocket();
                _client.Options.AddSubProtocol("graphql-ws");
                _client.Options.SetRequestHeader("host", "<HOST URL without wss but now with 'realtime' text in api url because otherwise we are getting SSL error>");
                _client.Options.SetRequestHeader("x-api-key", "<API KEY>");

                await _client.ConnectAsync(new Uri("https://<MY-APPSYNC_API_PATH>.appsync-realtime-api.<AWS-region>.amazonaws.com/graphql"), CancellationToken.None);
                await SendCommand();
                var docList = await Receive();
            }
            catch(Exception ex)
            {

            }
        }

       static  private async Task SendCommand()
        {
            ArraySegment<byte> outputBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes("'query' : 'subscription SubscribeToEventComments{ subscribeToEventComments(eventId: 'test'){  content }}'"));
            await _client.SendAsync(outputBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }
        static private async Task<string> Receive()
        {
            var receiveBufferSize = 1536;
            byte[] buffer = new byte[receiveBufferSize];
            var result = await _client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            var resultJson = (new UTF8Encoding()).GetString(buffer);
            return resultJson;
        }
我得到以下例外:

内部异常:“主机中的软件中止了已建立的连接。”

内部异常消息:“无法从传输连接读取数据:主机中的软件中止了已建立的连接…”

消息:“远程方在未完成关闭握手的情况下关闭了WebSocket连接。”


任何人都可以帮助正确的实现。

Nuget无法在AppSync订阅中立即运行,因此您需要为此编写自己的客户端代码,就像您在第二个(非Nuget)示例中尝试的那样

现在,对于第二个示例,再看一看问题中引用的。有几个步骤没有包含在代码中。我将列举所需的步骤,并尝试将它们从python代码移植到C(请注意,我手头没有C环境,因此可能存在语法错误,但此代码应该非常接近您所需要的)

步骤0-AppSync终结点 假设为您的api调用aws appsync get graphql api--api id Example23456的结果为:

{
“graphqlApi”:{
“名称”:“myNewRealTimeGraphQL API”,
“authenticationType”:“,
“标记”:{},
“APID”:“示例123456”,
“URI”:{
“GRAPHQL”:”https://abc.appsync-api.us-west-2.amazonaws.com/graphql",
“实时”:wss://abc.appsync-realtime-api.us-west-2.amazonaws.com/graphql"
},
“arn”:“arn:aws:appsync:us-west-2:XXXXXXXXXXXXXX:API/XXXXXXXXXXXXXX”
}
}
步骤1-构建连接URL 步骤2-连接到WebSocket端点 这包括按照python文章中提到的协议发送connection_init消息

步骤3-根据协议等待连接确认 同样,这是按照协议进行的

步骤4-注册订阅 第5步-发送变异 此步骤不在此响应中,但可通过AWS控制台完成

步骤6-等待“数据”消息 这些是AppSync发送的实时事件

步骤7-注销订阅 步骤8-断开连接
//这些声明与您的_客户机处于同一级别
//这来自步骤0中的graphqlApi.uris.GRAPHQL,为了清晰起见,在这里设置为var
_gqlHost=“abc.appsync api.us-west-2.amazonaws.com”;
//这来自步骤0中的graphqlApi.uris.REALTIME,为清晰起见,此处设置为var
_realtimeUri=”wss://abc.appsync-realtime-api.us-west-2.amazonaws.com/graphql";
_apiKey=“”;
静态公共异步任务CallWebsocket()
{
//第一步
//这是服务器需要的JSON,它将转换为base64
//(注意:对于此任务,最好使用类似Json.NET的东西)
var header=var test=$@”{{
“主机”:“{gqlHost}”,
“x-api-key”:“{u-apiKey}”
}}";
//现在我们需要将前面的JSON编码为base64
var headerB64=System.Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(header));
UriBuilder connectionUriBuilder=新的UriBuilder(_realtimeUri);
connectionUriBuilder.Query=$“header={headerB64}&payload=e30=”;
尝试
{
_client=newclientwebsocket();
_client.Options.addSubtocol(“graphql-ws”);
//步骤2
wait_client.ConnectAsync(connectionUriBuilder.Uri),CancellationToken.None);
//步骤3
等待SendConnectionInit();
等待接收();
}
捕获(例外情况除外)
{
}
}
静态专用异步任务SendConnectionInit()
{
ArraySegment outputBuffer=新的ArraySegment(Encoding.UTF8.GetBytes(@“{”type“:“connection_init”}”);
wait_client.SendAsync(outputBuffer,WebSocketMessageType.Text,true,CancellationToken.None);
}
静态专用异步任务SendSubscription()
{
//这个细节很重要,请注意订阅是一个字符串化的JSON,将嵌入下面的“数据”字段中
var subscription=$@“{{\”“query\”“:\”“subscription SubscribeToEventComments{{{SubscribeToEventComments{{{content}}}}}\”,\“variables\”“:{{}}}”;
变量寄存器=$@“{{
“”id“”:“”“”,
“有效载荷”:{{
“数据”:“{subscription}”,
“扩展名”:{{
“授权”:{{
“主机”:“{gqlHost}”,
“x-api-key”:“{u-apiKey}”
}}
}}
}},
“”类型“”:“”开始“”
}}";
//输出应该如下所示,再次注意“data”字段包含表示订阅的字符串化JSON
/*
{
“id”:“,
“有效载荷”:{
“数据”:“{\”查询\“:\”订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅订阅,
“扩展”:{
“授权”:{
“主机”:“abc.appsync api.us-west-2.amazonaws.com”,
“x-api-key”:”
}
}
},
“类型”:“开始”
}
*/
ArraySegment outputBuffer=新的ArraySegment(Encoding.UTF8.GetBytes(register));
wait_client.SendAsync(outputBuffer,WebSocketMessageType.Text,true,CancellationToken.None);
}
静态专用异步任务注销器()
{
var注销器=$@“{{
“”类型“”:“”停止“”,
“id”:”
}}"
ArraySegment outputBuffer=新的ArraySegment(Encoding.UTF8.GetBytes)(注销
//Create Client Specify eithen APIKey or AuthToken
var Client = new AppSyncClient("<Appsync URL>", new AuthOptions()
{
// APIKey = "<API Key>",
AuthToken = "<JWT Token>"
});

//To Subscribe an query
Guid newId = Guid.NewGuid();
await Client.CreateSubscriptionAsync<Message>(new QueryOptions()
{
Query = "subscription <Subscription Query>",
SubscriptionId = newId
},
(data) =>
{

});

//To unsubscribe an subscription
await Client.UnSubscribe(newId);

//To close the websocket
await Client.Close();