amplify-cli: Failed to construct 'WebSocket' when using amplify mock over http

Copied from an upstream amplify-cli issue as reported by @riacoding:

Describe the bug Create a fresh react project and add amplify to it with an API. On running amplify mock api the graphql subscriptions are not working as expected with the AWSAppSyncRealTimeProvider having a connection failed exception after timeout.

Amplify CLI Version Amplify/Cli@4.5.0

To Reproduce Following demo from aws blog post by Nikhil Dabhade https://aws.amazon.com/blogs/mobile/amplify-framework-local-mocking/

npx create-react-app myapp amplify init amplify add api npm i aws-amplify replace App.js with code below

import React, { useEffect, useReducer } from “react”; import Amplify from “@aws-amplify/core”; import { API, graphqlOperation } from “aws-amplify”; import { createTodo } from “./graphql/mutations”; import { listTodos } from “./graphql/queries”; import { onCreateTodo, onUpdateTodo } from “./graphql/subscriptions”;

import config from “./aws-exports”; Amplify.configure(config); // Configure Amplify

const initialState = { todos: [] }; const reducer = (state, action) => { switch (action.type) { case “QUERY”: return { …state, todos: action.todos }; case “SUBSCRIPTION”: return { …state, todos: […state.todos, action.todo] }; default: return state; } };

async function createNewTodo() { const todo = { name: “Use AppSync”, description: “Realtime and Offline” }; await API.graphql(graphqlOperation(createTodo, { input: todo })); } function App() { const [state, dispatch] = useReducer(reducer, initialState);

useEffect(() => { getData(); const subscription = API.graphql(graphqlOperation(onCreateTodo)).subscribe({ next: eventData => { const todo = eventData.value.data.onCreateTodo; dispatch({ type: “SUBSCRIPTION”, todo }); } }); return () => { subscription.unsubscribe(); }; }, []);

async function getData() { const todoData = await API.graphql(graphqlOperation(listTodos)); dispatch({ type: “QUERY”, todos: todoData.data.listTodos.items }); }

return ( <div> <div className="App"> <button onClick={createNewTodo}>Add Todo</button> </div> <div> {state.todos.map((todo, i) => (

{todo.name} : {todo.description}

))} </div> </div> ); } export default App; amplify mock api npm start

Expected behavior From the http://localhost:20002/ local endpoint using graphiql to create a mutation create a todo item. This would then be automatically updated on the http://localhost:3000/ endpoint via the graphql subscription.

The error appears to happen because new Websocket is called with a string that starts with http:// instead of the required ws:// or wss://.

https:// is replaced with wss:// here.

Suggest adding a line that replaces http:// with ws:// to enable supporting subscriptions with amplify mock which runs locally on http:// by default.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 21 (6 by maintainers)

Commits related to this issue

Most upvoted comments

We have this issue on our backlog. We will be picking this up once it is prioritized

The change is released in Amplify CLI 4.18.1

@kaustavghosh06 . Thanks for the follow up. We realize it’s on local mock only… but when it worked on local mock it made it a breeze to test. Now we have to deploy in order to know if a feature that depends on a subscription works as intended… and deployments are never usually quick.

Fixing this on local would help speed up the process.

@arnm Mock does not support DataStore yet. We have are tracking this in aws-amplify/amplify-category-api#322

Hey guys, this issue is tied only to mock/local-testing for subscriptions and in now way affect your deployed app. We’re actively working on fixing this issue.

@yuth . Do you have any suggested workarounds for this issue…or a timeline of when it can be address? Our app is ramping up the use of using subscriptions and we have to do a publish each time to make this work… I am guessing there is a better way? Thanks for your help

@yuth Hey, thanks for the fix. However, I have updated to Amplify CLI 4.18.1 and I still get the same error. It may be slightly different in my scenario because I’m getting this error from Datastore.

DataStore - Sync error subscription failed Connection failed: Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.

EDIT: I updated from aws-amplify 3.0.5 to 3.0.9 and aws-amplify-react from 4.0.x to 4.1.8 after updated to Amplify CLI 4.18.1 and everything seems to be working great now! Have been having issue for a while but glad it has been resolved!

I believe the workshop used an older version of the amplify Lib when it was using MQTT instead of Web sockets that it currently uses

On Sat, Mar 14, 2020 at 8:09 PM Rafael Sorto notifications@github.com wrote:

What I don’t understand is how come this worked on Nader Dabit’s workshop and now it doesn’t work?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-cli/issues/3008#issuecomment-599161812, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACZHNXV2LZQA4NH2YN7N3LRHRBGBANCNFSM4J3TND6A .

What I don’t understand is how come this worked on Nader Dabit’s workshop and now it doesn’t work?

@yuth Any updates? Just ran into this as well. Could you link the issue in the backlog so we can track it?

Amplify Mock has only support MQTT for subscriptions. We have a backlog item to add support for websockets