Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

watch method on RemoteMongoCollection in ReactNative #209

Closed
adrian-gierakowski opened this issue Jan 30, 2019 · 6 comments
Closed

watch method on RemoteMongoCollection in ReactNative #209

adrian-gierakowski opened this issue Jan 30, 2019 · 6 comments

Comments

@adrian-gierakowski
Copy link

Creating this issue as advised by @adamchel in #23

@adamchel
Copy link
Contributor

adamchel commented Feb 4, 2019

Hi @adrian-gierakowski thanks for filing this issue.

As per react-native-community/discussions-and-proposals#99, we are planning on contributing support for server-sent events in React Native, which will allow us to implement this without resorting to a hack around XmlHttpRequest.

We hope to start work on this in the coming weeks!

@adrian-gierakowski
Copy link
Author

Hi @adamchel. Has there been any progress on this?

@adamchel
Copy link
Contributor

@adrian-gierakowski

This work got re-prioritized, so I wasn't able to work on it as soon as I would have liked, but I've finally opened a PR on the official React Native repo, so hopefully we will be able to support this soon!

facebook/react-native#25718

@adrian-gierakowski
Copy link
Author

That's great news @adamchel. Can't wait to try it out.

facebook-github-bot pushed a commit to facebook/react-native that referenced this issue Sep 11, 2019
Summary:
This PR introduces the `EventSource` web standard as a first-class networking feature in React Native. In the discussion we had in February at react-native-community/discussions-and-proposals#99, cpojer indicated that the RN maintainers would be willing to accept a PR to offer this functionality.

The linked discussion goes into detail about why this change must happen in React Native Core as opposed to a community library, but the tl;dr is that `XmlHttpRequest` doesn't let you do streaming in a resource-efficient way, since it holds onto the entire response buffer until the request is complete. When processing a stream that might last for a long time, that's not ideal since there might be a lot of data in that buffer that is now useless to maintain.

For more information about EventSource and server-sent events, check out these links:
* [EventSource on MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)
* [Using server-sent events on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
* [WHATWG spec for server-sent events](https://html.spec.whatwg.org/multipage/server-sent-events.html)

I've tried as best as I can to satisfy the linked specification so that this is as standard as possible.

One of the projects I maintain has an ideal use case for this feature. The SDK for MongoDB Stitch (a backend-as-a-service for the MongoDB database) has the ability to open a "change stream" to watch for changes that happen on a database. However, in our JavaScript SDK, this feature depends on `EventSource`, because the backend service implements the one-way streaming protocol with server-sent events. We know there is demand for this feature because users have requested it: mongodb/stitch-js-sdk#209.

If this PR will be accepted, I am happy to update the `Networking` documentation at https://facebook.github.io/react-native/docs/network

## Changelog

[JavaScript] [Added] Implements the `EventSource` web standard in `Libraries/Networking`
[JavaScript] [Added] Exposes the `EventSource` implementation in `Libraries/Core/setUpXHR.js`
Pull Request resolved: #25718

Test Plan:
To test the `EventSource` implementation, I added a comprehensive set of unit tests that cover the basic functionality, as well as edge cases that are laid out in the spec. See `EventSource-test.js` for the cases that the tests handles. For convenience, I've also included the test descriptions as produced by the `jest` test output here.

```
 PASS  Libraries/Network/__tests__/EventSource-test.js
  EventSource
    ✓ should pass along the correct request parameters (527ms)
    ✓ should transition readyState correctly for successful requests (4ms)
    ✓ should call onerror function when server responds with an HTTP error (2ms)
    ✓ should call onerror on non event-stream responses (1ms)
    ✓ should call onerror function when request times out (1ms)
    ✓ should call onerror if connection cannot be established (1ms)
    ✓ should call onopen function when stream is opened (1ms)
    ✓ should follow HTTP redirects (2ms)
    ✓ should call onmessage when receiving an unnamed event (2ms)
    ✓ should handle events with multiple lines of data (1ms)
    ✓ should call appropriate handler when receiving a named event (1ms)
    ✓ should receive multiple events (1ms)
    ✓ should handle messages sent in separate chunks (1ms)
    ✓ should forward server-sent errors
    ✓ should ignore comment lines (1ms)
    ✓ should properly set lastEventId based on server message (1ms)
    ✓ should properly set reconnect interval based on server message
    ✓ should handle messages with non-ASCII characters (1ms)
    ✓ should properly pass along withCredentials option (3ms)
    ✓ should properly pass along extra headers (1ms)
    ✓ should properly pass along configured lastEventId (2ms)
    ✓ should reconnect gracefully and properly pass lastEventId (9ms)
    ✓ should stop attempting to reconnect after five failed attempts (2ms)
```

As a manual E2E test, I also added streaming support to the Stitch React Native SDK, and tested it with my React Native EventSource implementation, and confirmed that our `EventSource`-based streaming implementation worked with this `EventSource` implementation.
* Source code for E2E app test: https://gist.github.com/adamchel/6db456c1a851ed7dd20b54f6db3a6759
* PR for streaming support on our React Native SDK: mongodb/stitch-js-sdk#294
* Very brief video demonstrating E2E functionality: https://youtu.be/-OoIpkAxmcw

Differential Revision: D17283890

Pulled By: cpojer

fbshipit-source-id: 0e9e079bdb2d795dd0b6fa8a9a9fa1e840245a51
@BrianIto
Copy link

BrianIto commented Oct 9, 2019

Hello Adam! I'm Brian and can't wait to see it working. You did it in a Video in this link right?

It was great to the see! Any news please keep us on touch! Thank y'all for your work!

@adamchel
Copy link
Contributor

Hey everyone, we've just released experimental watch support for React Native! See https://github.com/mongodb/stitch-js-sdk/releases/tag/v4.9.0 for details on how you can use it. We can release this non-experimentally once React Native 0.62 is officially released.

If you have any problems with it, feel free to open a new issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants