sinclairzx81 / smoke

Run Web Servers in Web Browsers over WebRTC
Other
536 stars 40 forks source link

How to recreate connection class from existing connection? #22

Closed minwidth0px closed 1 month ago

minwidth0px commented 1 month ago

For example, If a user goes to another page, they will lose the current network class and will have to create a new one and redo all the signaling. Is there a way to recreate a network once a connection was already established? For example to recreate the network from an sdp answer and list of candidates? I tried creating a mock Hub class that re-uses the address and sdp params instead of trying to fetch them but it did not work: (It times out in the async connect(remoteAddress, port) function):


  constructor(endpoint: string, address: string, ICEParams: any) {
    this.#ICEParams = ICEParams //<-- list of SDP answer and candidates saved from the real hub class
    this.#address = address
    this.#receiveCallback = () => {}
  }
  //...
  public send(message: { to: string; data: any }): Promise<void> {
    if(!this.#isSet){//only set the params once
        this.#isSet = true
        const ICEParams = this.#ICEParams
        for (let i = 0; i < ICEParams.params.length; i++){
            this.#onReceive(ICEParams.params[i])
        }
    }
  }

I want this feature because currently I am setting the SDP and and candidates manually (ie. the send function prints the SDP and candidates to the page, and onReceive is called when you paste the SDP/candidates into a textarea) so reconnecting on each page load would take a long time. I would like to be able to just store some info in sessionStorage/localStorage that can re-create the existing connection newtork class (serializing deeply nested classes is impossible in JS, so I can't just do that).

sinclairzx81 commented 1 month ago

@minwidth0px Hiya,

For example, If a user goes to another page, they will lose the current network class and will have to create a new one and redo all the signaling. Is there a way to recreate a network once a connection was already established? For example to recreate the network from an sdp answer and list of candidates? I tried creating a mock Hub class that re-uses the address and sdp params instead of trying to fetch them but it did not work: (It times out in the async connect(remoteAddress, port) function):

Smoke leaves many of these details open ended (as there is no one size fits all solution to handling what happens if a user closes a page). However, the Signaling / Hub setup is partially written in support of the idea that Hub connections can be authorized (using standard bearer tokens) and that from authorized connection, a unique address that is consistent between page loads can be achieved (but you really need to authorize a connection for this, and handle cases like duplicate connections from multiple browser tabs, etc...all open ended questions)

If you are building applications with Smoke, it's helpful to embrace the idea that servers will be completely transient and may disappear at any time when users reload or close pages. This should inform your application design and you should be working within the bounds of this core constraint (although running WebRTC servers in more persistent environments, like electron might facilitate less transience of servers)

It looks like you were using Sidewinder in one of your projects, This should provide basis for Hub signaling + authorization as mentioned above. I am actually the author of Sidewinder, so if you have any question using it, feel free to ping either here or on the Sidewinder project at the following URL

https://github.com/sinclairzx81/sidewinder

Hope this helps S

sinclairzx81 commented 1 month ago

@minwidth0px Will close off this issue for now, but if you have any follow up questions, feel free to ping on this thread

Cheers!

minwidth0px commented 1 month ago

@sinclairzx81 Thanks for the detailed reply.

it's helpful to embrace the idea that servers will be completely transient and may disappear at any time when users reload or close pages.

By "go to another page" I meant more like if I'm on index.html, and then I click on about.html, I will lose the connection there. I wouldn't expect the server to disappear within that time. Basically, what I want is to create a connect.html page where the user can decide what kind of signaling method they want to use - eg. manually pasting SDPs, public webtorrent trackers, a private websocket server they own ect. and after they connect, they can continue to the actual page they want, eg. content.html, which will use smoke for some of the requests. Right now when I click on another page everything is reset and there is no good way to maintain state across pages on the web. The best there is is localstorage, which can only contain text but not objects like a Network class.

although running WebRTC servers in more persistent environments, like electron might facilitate less transience of servers

Something like this is or headless chrome actually more or less on my to do list. Either this or looking into how difficult it would be to support nodejs as a platform. I think it should be just as simple as giving an option to pass a wrtc variable that is assigned by wrtc = require('node-webrtc') but I haven't looked into it yet.