Comments (15)
Thanks, @NeoPhi! Using the implementation directly, we are running into another issue:
Unable to find native implementation, or alternative implementation for WebSocket!
at new SubscriptionClient (node_modules/subscriptions-transport-ws/dist/client.js:20:19)
at Object.done (src/__tests__/socket-test.js:46:5)
at process._tickCallback (internal/process/next_tick.js:103:7)
from subscriptions-transport-ws.
@NeoPhi, thanks! The new error after passing in the WebSocket explicitly:
TypeError: this.wsImpl is not a constructor
at SubscriptionClient.Object.<anonymous>.SubscriptionClient.connect (node_modules/subscriptions-transport-ws/dist/client.js:155:23)
at new SubscriptionClient (node_modules/subscriptions-transport-ws/dist/client.js:36:14)
at Object.done (src/__tests__/socket-test.js:46:5)
from subscriptions-transport-ws.
Just to add to @jayhuang75 comments, we are using Jest for our unit testing. We tried creating a simple test based on the unittest code that comes with the package within our test suite:
import * as WebSocket from 'ws';
import { SubscriptionServer, SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws';
import {createServer, IncomingMessage, ServerResponse} from 'http';
const RAW_TEST_PORT = 8091;
const httpServerRaw = createServer(notFoundRequestListener);
httpServerRaw.listen(RAW_TEST_PORT);
Object.assign(global, {
WebSocket: WebSocket,
});
function notFoundRequestListener(request: IncomingMessage, response: ServerResponse) {
response.writeHead(404);
response.end();
}
describe('Client', function () {
let wsServer: WebSocket.Server;
beforeEach(() => {
wsServer = new WebSocket.Server({
server: httpServerRaw,
});
});
afterEach(() => {
if (wsServer) {
wsServer.close();
}
});
it('should send INIT message when creating the connection', (done) => {
wsServer.on('connection', (connection: any) => {
connection.on('message', (message: any) => {
const parsedMessage = JSON.parse(message);
expect(parsedMessage.type).to.equals('init');
done();
});
});
new SubscriptionClient(`ws://localhost:${RAW_TEST_PORT}/`);
});
});
Fails with:
FAIL src/__tests__/socketTest.js
● Client › should send INIT message when creating the connection
TypeError: _subscriptionsTransportWs.SubscriptionClient is not a constructor
at Object.done ( src/__tests__/socketTest.js:44:5)
at process._tickCallback (internal/process/next_tick.js:103:7)
from subscriptions-transport-ws.
The workaround for the time being is to use:
import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws/dist/client';
from subscriptions-transport-ws.
You'll need to use the optional 3rd argument to the SubscriptionClient to specify the WebSocket implementation it should use. Something like this (untested) should work:
import WebSocket from 'ws';
import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws/dist/client';
new SubscriptionClient('url', {}, WebSocket);
from subscriptions-transport-ws.
@NeoPhi, yep, had already tried that without luck:
new SubscriptionClient(`ws://localhost:${RAW_TEST_PORT}/`, {
reconnect: true,
connectionParams: {
}, WebSocket
});
None of the unit tests for the library seem to require these optional parameters though.
I would think the below statement in the unit test should ensure that SubscriptionClient#Line6 get a WebSocket definition when it is looking for one.
Object.assign(global, {
WebSocket: WebSocket,
});
from subscriptions-transport-ws.
In your code sample you have the WebSocket within the options
argument, it is a separate 3rd argument being passed to the SubscriptionClient.
The unit tests work since they explicitly import the client after ensuring that the global WebSocket reference is installed. I find that approach fragile as it is non-obvious and depending on the transpiler you are using may get reordered so prefer to pass in the implementation explicitly.
from subscriptions-transport-ws.
The import should be import WebSocket from 'ws';
instead of import * as WebSocket from 'ws';
from subscriptions-transport-ws.
Thanks for your help, @NeoPhi! It works now.
For reference, these were the required changes to get things working:
-
Use SubscriptionClient implementation directly instead of interface.
import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws/dist/client';
-
Pass in WebSocket object when invoking SubscriptionClient constructor.
new SubscriptionClient(`ws://localhost:${RAW_TEST_PORT}/`, {
reconnect: true,
connectionParams: {
}
}, WebSocket);
- Use
import WebSocket from 'ws';
instead ofimport * as WebSocket from 'ws';
from subscriptions-transport-ws.
Thanks for the help @jeanabraham @NeoPhi I follow the steps and yes the unit testing is pass. But once Im on the step 2, pass in WebSocket object
new SubscriptionClient(
ws://localhost:${RAW_TEST_PORT}/, { reconnect: true, connectionParams: { } }, WebSocket);
the application is break with one warning. (can not receiving any websocket data no more)
./~/bindings/bindings.js Critical dependencies: 76:22-40 the request of a dependency is an expression 76:43-53 the request of a dependency is an expression @ ./~/bindings/bindings.js 76:22-40 76:43-53
And just for your information the GraphQL websocket server is running and once I remove the WebSocket object from the SubscriptionClient constructor, everything is back to normal, but the unit testing fail because of this reason
`
Unable to find native implementation, or alternative implementation for WebSocket!
at new SubscriptionClient (node_modules/subscriptions-transport-ws/dist/client.js:20:19)
at Object.done (src/__tests__/socket-test.js:46:5)
at process._tickCallback (internal/process/next_tick.js:103:7)`
from subscriptions-transport-ws.
@jayhuang75 , looks like there were few issues here.
-
that fact that you couldn't import
subscriptionClient
for test on Node.
This was fixed in the latest release (0.5.4
).
Now you can just doimport {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws'
. -
In Node environment (where the tests run), you don't have native WebSockets implementation, so you have to use an alternative in the following format:
import * as WebSocket from 'ws';
You can either assign it to the global like @jeanabraham pointed out:
Object.assign(global, {
WebSocket: WebSocket,
});
or you can pass the external websocket to subscriptionClient
constructor as a third param like @NeoPhi has pointed out:
new SubscriptionClient('url', {}, WebSocket);
But as for your last comment, remember to close the websocket connection after each test. that might be related to your last problem.
To check out how we close that you can look at our tests file here: https://github.com/apollographql/subscriptions-transport-ws/blob/master/src/test/tests.ts#L213-L217
Please let me know it that solved your problems and we can close that issue
from subscriptions-transport-ws.
from subscriptions-transport-ws.
@Urigo I follow your recommendation. The only weird issues is once I add the WebSocket to my subscriptionClient constructor
const wsClient = new SubscriptionClient("ws://my-webscoket-url", { reconnect: true, reconnectionAttempts: 1, connectionParams: { // Pass any arguments you want for initialization }, }, WebSocket);
and the Request URL will replace my url
ws://my-webscoket-url
by the
ws://localhost:3000/sockjs-node/393/vdcpziqp/websocket
and my WebSocket implementation break.
Any idea?
from subscriptions-transport-ws.
@jayhuang75 , when exactly do you notice that the URL changes? after the socket initialized?
Also, do you use ws
package as client, right?
from subscriptions-transport-ws.
Closing for now. A lot has changed since this issue was opened.
@jayhuang75 if this issue is still relevant, please re-open or create a new issue.
from subscriptions-transport-ws.
Related Issues (20)
- Unhandled GraphQL subscription error Error: Cannot read property 'load' of undefined
- How do I pull maxConnectTimeGenerator from SubscriptionClient?
- Subscription unsubscribing when getting a graphQLError HOT 1
- How Do I Know When Subscriptions Ready on Server and Client ??
- Is there any way to pass authorization token to subscribe dynamically?
- CVE-2021-32640 / SNYK-JS-WS-1296835 Regular Expression Denial of Service in [email protected]
- How to fix 'Cannot read property 'id' of 'null'
- A vulnerability was detected in the ws package. HOT 2
- onConnected and onReconnected event do not fire HOT 1
- "Cannot read property 'subscribe' of undefined" HOT 3
- Use async/await in npm distribution to improve stack traces
- Next.js + Apollo Server 3.0 + Subscription HOT 2
- How to use at AWS Lambda, use serverless?
- Dependency Dashboard
- socket.protocol is empty string when connecting
- How to use SubscriptionClient to get onclose code information
- GQL_CONNECTION_INIT is sometimes delivered AFTER GQL_START, because connectionParams is resolved asynchronously HOT 1
- Outdated Readme? HOT 3
- Error: Unable to find native implementation, or alternative implementation for WebSocket!
- `.return` is called to unsubscribe a subscription even after it has already thrown an error
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from subscriptions-transport-ws.