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

Add support for native to web cross-play #47

Closed
johanhelsing opened this issue Oct 27, 2022 · 7 comments
Closed

Add support for native to web cross-play #47

johanhelsing opened this issue Oct 27, 2022 · 7 comments
Labels
enhancement New feature or request

Comments

@johanhelsing
Copy link
Owner

There are some small incompatibilities between the native and wasm implementation that makes connections fail.

The native version implements ICE candidate trickling, while the wasm version does not. (#16)

@johanhelsing johanhelsing added the enhancement New feature or request label Oct 27, 2022
@rozgo
Copy link
Contributor

rozgo commented Nov 26, 2022

One of our projects needs this to work. I'll look into this and report back.

@johanhelsing
Copy link
Owner Author

@rozgo How did it go?

@rozgo
Copy link
Contributor

rozgo commented Dec 11, 2022

I've got it in a state where it should be working, but its not. So far, I'm getting ICE candidates, sending them to connected peers, with ICE trickling enabled. But still works among native or WASM, but not both. I had to pause this last week, but will look into it again on Monday.

Minor changes:

    let ice_server_config_list = [ice_server_config];
    peer_config.ice_servers(&serde_wasm_bindgen::to_value(&ice_server_config_list).unwrap());
    peer_config.ice_transport_policy(RtcIceTransportPolicy::Relay);
    RtcPeerConnection::new_with_configuration(&peer_config).unwrap();

Listening for OnIceCandidates:

    let signal_peer_ice = signal_peer.clone();
    let onicecandidate: Box<dyn FnMut(JsValue)> = Box::new(move |event| {
        let event = Reflect::get(&event, &JsValue::from_str("candidate")).efix();
        if let Ok(event) = event {
            if let Ok(candidate) = event.dyn_into::<RtcIceCandidate>() {
                info!("ICE candidate: {:?}", candidate);
                signal_peer_ice.send(PeerSignal::IceCandidate(candidate.candidate()));
            }
        }
    });
    let onicecandidate = Closure::wrap(onicecandidate);
    conn.set_onicecandidate(Some(onicecandidate.as_ref().unchecked_ref()));

Handling the new candidate with existing message:

            PeerSignal::IceCandidate(candidate) => {
                // Add ice candidate
                info!("ICE CANDIDATE ADDING: {:?}", candidate);
                candidates.push(candidate);
            }

image

NOTE: I noticed right before I had to move on, that the signaling server was not properly handling Native and WASM, at least it the minimal demo Im using. So it might be something simple, and things might work after that.

@rozgo
Copy link
Contributor

rozgo commented Dec 13, 2022

Ok, I got back into this. Made some progress and got WASM communicating to Native but breaks in the other direction. I think I understand the ICE back and forth chatter requirements for trickling now. Should have more info by EOD.

Basically, I'm selecting for receiving ICE candidates and checking if data channel is ready, all while sending ICE candidates to remote peers.

    loop {
        select! {
            _ = channel_ready_rx.next() => {
                debug!("channel ready");
                break;
            }
            msg = signal_receiver.next() => {
                if let Some(PeerSignal::IceCandidate(candidate)) = msg {
                    debug!("got an IceCandidate signal! {}", candidate);
                    let mut ice_candidate: RtcIceCandidateInit = RtcIceCandidateInit::new(&candidate);
                    ice_candidate.sdp_m_line_index(Some(0));
                    JsFuture::from(
                        conn.add_ice_candidate_with_opt_rtc_ice_candidate_init(Some(&ice_candidate)),
                    )
                    .await
                    .efix()?;
                }
            }
        };
    }
    let signal_peer_ice = signal_peer.clone();
    let onicecandidate: Box<dyn FnMut(JsValue)> = Box::new(move |event| {
        let event = Reflect::get(&event, &JsValue::from_str("candidate")).efix();
        if let Ok(event) = event {
            if let Ok(candidate) = event.dyn_into::<RtcIceCandidate>() {
                debug!("sending IceCandidate signal {}", candidate.candidate());
                signal_peer_ice.send(PeerSignal::IceCandidate(candidate.candidate()));
            }
        }
    });
    let onicecandidate = Closure::wrap(onicecandidate);
    conn.set_onicecandidate(Some(onicecandidate.as_ref().unchecked_ref()));

@rozgo
Copy link
Contributor

rozgo commented Dec 13, 2022

Ok, it works. will clean up the code and submit a PR tonight.

image

@johanhelsing
Copy link
Owner Author

Awesome! I'll have some time today and tomorrow to review it

@johanhelsing
Copy link
Owner Author

Done in #54 🎉

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

No branches or pull requests

2 participants