aws / aws/aws-appsync-community

AppSync's WS connection closing at initialization

Open
#350 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
HTML
Stars
507
Forks
37
PR merge metrics
No merged PRs in 30d

Description

Currently working on a C# client to subscribe to AppSync mutations. I'm trying to follow the example listed in [this](https://github.com/graphql-dotnet/graphql-client/issues/372#issuecomment-990590565) previously closed issue with my own AppSync setup. However, when the code hits the `.InitializeWebSocketConnection`, I get a relatively vague WebSocketException saying `The remote party closed the WebSocket connection without completing the close handshake`. Here is my current code

```
public class AppSyncHeader
{
[JsonPropertyName("host")]
public string Host { get; set; }

[JsonPropertyName("x-api-key")]
public string ApiKey { get; set; }

public string ToJson()
{
return JsonSerializer.Serialize(this);
}

public string ToBase64String()
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes(ToJson()));
}
}

public class AuthorizedAppSyncHttpRequest : GraphQLHttpRequest
{
private readonly string _authorization;

public AuthorizedAppSyncHttpRequest(GraphQLRequest request, string authorization) : base(request) =>
_authorization = authorization;

public override HttpRequestMessage ToHttpRequestMessage(
GraphQLHttpClientOptions options,
IGraphQLJsonSerializer serializer
)
{
HttpRequestMessage result = base.ToHttpRequestMessage(options, serializer);
result.Headers.Add("X-Api-Key", _authorization);
return result;
}
}

public static async Task Main(string[] args)
{
var regularHost = "xxxxxx.appsync-api.us-east-1.amazonaws.com";
var wsHost = "xxxxxx.appsync-realtime-api.us-east-1.amazonaws.com";
var apiKey = "foobar";

var client = new GraphQLHttpClient(
$"https://{regularHost}/graphql",
new SystemTextJsonSerializer(
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }
)
);

var appSyncHeader = new AppSyncHeader { Host = regularHost, ApiKey = apiKey, };

string header = appSyncHeader.ToBase64String();

client.Options.WebSocketEndPoint = new Uri($"wss://{wsHost}/graphql?header={header}&payload=e30=");
client.Options.PreprocessRequest = (req, client) =>
{
GraphQLHttpRequest result = new AuthorizedAppSyncHttpRequest(req, apiKey)
{
["data"] = JsonSerializer.Serialize(req),
["extensions"] = new { authorization = appSyncHeader, }
};
return Task.FromResult(result);
};

await client.InitializeWebsocketConnection();
}
```
Would anyone happen to know why the server is rejecting the connection? I was able to test out the endpoint locally with Postman's WebSocket feature and the connection was able to be initialized and was able to start receiving the KA messages.

Contributor guide

Open the contributing guide

Research direction

Review the C# snippet around InitializeWebsocketConnection, the WebSocketEndPoint, and the AppSync authorization headers, then compare its handshake with the successful Postman WebSocket connection. Done means identifying why AppSync rejects this client initialization and confirming that the connection succeeds and receives KA messages.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.