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

feat(runtime,serverless,cli): add WebSocket support #887

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

akitaSummer
Copy link
Contributor

@akitaSummer akitaSummer commented May 20, 2023

Now you can use websocket.

But the Event is incorrect, I temporarily used @ts-ignore to hack, I hope you can solve this problem in the future, and we still lack CloseEvent and ErrorEvent.

#794

@changeset-bot
Copy link

changeset-bot bot commented May 20, 2023

🦋 Changeset detected

Latest commit: 878d496

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@lagon/cli Patch
@lagon/runtime Patch
@lagon/serverless Patch
@lagon/js-runtime Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented May 20, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
storybook ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 20, 2023 6:02pm

@vercel
Copy link

vercel bot commented May 20, 2023

@akitaSummer is attempting to deploy a commit to the Lagon Team on Vercel.

A member of the Team first needs to authorize it.

@akitaSummer
Copy link
Contributor Author

This pr did not take into account the link reuse of websockets in distributed scenarios. I think there is still more optimization.

@QuiiBz
Copy link
Member

QuiiBz commented May 20, 2023

Thanks a lot for this PR! I'll take a deep look at it tomorrow. We'll probably need to add some limits (e.g max number of open websockets, max message size, ...)

crates/runtime/tests/websocket.rs Outdated Show resolved Hide resolved
ws.send('test_ws');
ws.close();
// TODO: If you add this line, it will always block, but the correct logic is that if you don’t add this line, it will always block. I don’t understand why
// res();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we call res() on the close event?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that the current implementation should theoretically block the code at the await statement, but in practice, it continues execution until the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the comment on line 55 is uncommented, the code will block at the await statement. However, the correct logic should be to continue execution until the end.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly why I suggested #887 (comment): JS-land shouldn't manage or create a parallel event loop, it should be done in native-land. JS-land doesn't have access to the whole context, so it's almost impossible to make it work this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand the connection between JS-land and the bug in the current code. I think after line 54 is executed, the code should block at the await because res() is not called. Is this related to Native-land? Did Native-land resolve this promise?

Comment on lines 140 to 143
private async eventLoop() {
while (this._readyState !== WsState.CLOSED) {
try {
const data = await LagonAsync.websocketEvent(this.wsId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part should be moved inside the runtime's event loop directly (runtime_isolate/src/lib.rs), where we can call ws.next_message()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't agree with that. I believe this code involves modifying the state of the ws object in JavaScript and involves significant data interaction, such as creating an Event object. Therefore, I suggest performing the event loop on the JavaScript side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my answer here: #887 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reused the event loop in JS-land here, and I think it's not correct to handle events on the Native-land side. Firstly, as you can see from the code I wrote, I don't need much context information. I only need Native-land to tell me the current return value of ws, and then I trigger the corresponding subscriptions based on the return value. If I handle events on the Native-land side, the required content will not change, and triggering subscriptions can change the status of ws in JS-land, which can bring more costs. Maybe I have misunderstood your needs. If you have better ideas, can you directly modify this branch so that we can discuss further?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll push to this PR directly so you can better understand what I mean, and then we can discuss which solution is the best.

crates/runtime_websocket/src/lib.rs Outdated Show resolved Hide resolved
@QuiiBz
Copy link
Member

QuiiBz commented Jun 4, 2023

@akitaSummer I've rebased and updated the js-runtime code to fix the TypeScript errors and implement both CloseEvent and MessageEvent. Will check for #887 (comment) soon.

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

Successfully merging this pull request may close these issues.

WebSocket API
2 participants