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

Websocket communication #1151

Merged
merged 26 commits into from
Apr 24, 2023
Merged

Conversation

renkun-ken
Copy link
Member

@renkun-ken renkun-ken commented Jul 17, 2022

This is a very rough demo of using httpuv server in user R session and websockets on vscode side for communication.

If r.session.useWebSocket is enabled, a httpuv server is started in the background of an interactive R session, and vscode-R session watcher will create a WebSocket to connect to the server on attach.

The hover and completion of $ and @ are roughly implemented.

And it works on both local and remote development.

This makes it possible to address #440, #594, #837, #999.

Kapture.2023-03-29.at.22.18.53.mp4

@renkun-ken renkun-ken marked this pull request as draft July 17, 2022 15:42
@ElianHugh
Copy link
Collaborator

pretty neat! I tried this with an R6 object and it worked nicely. this could also have implications for liveshare requests

@Fred-Wu
Copy link

Fred-Wu commented Nov 25, 2022

Just would like to check whether there is any update and plan to release this implementation. Thanks.

@renkun-ken renkun-ken marked this pull request as ready for review March 29, 2023 14:13
@renkun-ken renkun-ken requested a review from ElianHugh March 29, 2023 14:21
@renkun-ken
Copy link
Member Author

Completion and hover are improved to support recursive $ and @.

@ElianHugh
Copy link
Collaborator

Works as expected for

a <- list(
    b = list(
        c = list(
            d = 5L
        )
    )
)

and

x <- setClass("student", slots = list(name = "character", age = "numeric", GPA = "numeric"))

Would it be worth allowing the socket ip address to be set by the user? Currently it's set to 127.0.0.1.
Also, is it possible to use unix domain sockets or windows pipes via httpuv::startPipeServer? I'm not sure if it returns the same messages as the standard socket server function

@renkun-ken
Copy link
Member Author

renkun-ken commented Mar 30, 2023

Would it be worth allowing the socket ip address to be set by the user? Currently it's set to 127.0.0.1.

Is there a use case for setting an ip other than 127.0.0.1? Since the session watcher itself still relies on a local filesystem to work properly, I'm not sure if it is useful to allow a websocket to attach to an IP other than 127.0.0.1.

Also, is it possible to use unix domain sockets or windows pipes via httpuv::startPipeServer? I'm not sure if it returns the same messages as the standard socket server function

The main point of using a httpuv websocket server in user R session and websocket in vscode-R extension here is that it does not block the user session and provides a simple event loop mechanism. I'm not sure if the bare bone socketServer or socketConnection could do the same easily?

Also, I'm thinking of using the Infinite Row Model to allow for dynamic loading of data frame in the viewer via WebSocket or http socket directly talking to the R session that creates that data viewer.

@ElianHugh
Copy link
Collaborator

ElianHugh commented Mar 30, 2023

Would it be worth allowing the socket ip address to be set by the user? Currently it's set to 127.0.0.1.

Is there a use case for setting an ip other than 127.0.0.1? Since the session watcher itself still relies on a local filesystem to work properly, I'm not sure if it is useful to allow a websocket to attach to an IP other than 127.0.0.1.

In 99% of situations, I'd say no, unless for whatever reason only IPv6 is allowed.

Also, is it possible to use unix domain sockets or windows pipes via httpuv::startPipeServer? I'm not sure if it returns the same messages as the standard socket server function

The main point of using a httpuv websocket server in user R session and websocket in vscode-R extension here is that it does not block the user session and provides a simple event loop mechanism. I'm not sure if the bare bone socketServer or socketConnection could do the same easily?

I've used socketConnection in the past, iland haven't run into major issues. Not sure of the major difference between it and httpuv admittedly. I might fiddle with the different socket implementations to see the differences

Also, I'm thinking of using the Infinite Row Model to allow for dynamic loading of data frame in the viewer via WebSocket or http socket directly talking to the R session that creates that data viewer.

Sounds like a good idea! I'll have a closer look at the PR tonight.

@renkun-ken
Copy link
Member Author

In 99% of situations, I'd say no, unless for whatever reason only IPv6 is allowed.

Good catch. Didn't think of/meet such scenario before. I'm curious how other R packages that start a web server (e.g. shiny) handle this?

I've used socketConnection in the past, iland haven't run into major issues. Not sure of the major difference between it and httpuv admittedly. I might fiddle with the different socket implementations to see the differences

If there is a good way to handle non-blocking communication between client and server via sockets, I'd be happy to see how we could adjust our implementation.

Sounds like a good idea! I'll have a closer look at the PR tonight.

Thanks, just take your time!

The dynamic loading of data frames will require another PR for certain, as I'm just playing around with the ag-grid api at master...renkun-ken:vscode-R:websocket-data-viewer but looks like there is more work such as server-side handling of filtering and ordering.

@ElianHugh
Copy link
Collaborator

So, I tried using httpuv::startPipeServer, and it appeared to work as expected.

I couldn't find much on IPv6 in R, so it might just be not super important ATM. I tried "localhost" but it looks like httpuv doesn't resolve names so no luck there.

@renkun-ken
Copy link
Member Author

renkun-ken commented Apr 1, 2023

I switch to using httpuv::startServer() to start a non-blocking http server and use fetch() on extension side. This could make it easier to implement dynamic data loading as we could directly access the R session's http server via resource uri inside the data viewer webview.

@renkun-ken
Copy link
Member Author

Let's merge this as an experimental feature first and see if it works properly under different scenarios.

@ElianHugh
Copy link
Collaborator

Sorry for the delay! I think that's a fair idea, we can get more feedback that way. Similar to how we handled rstudioapi and the session watcher

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

Successfully merging this pull request may close these issues.

3 participants