libp2p / libp2p/universal-connectivity
rust-peer not working on Windows
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 167
- Forks
- 75
- PR merge metrics
- No merged PRs in 30d
Description
Initial Problem
I've cloned the repo, and tried to run it with a simple cargo run.
However on Windows, the signal_hook::iterator::Signals is not available.
I've come up with a solution, but I'm not yet too familiar with rust in general, so I'm fairly certain that there is a better solution.
What I did
I made two configurations one for #[cfg(not(windows))] and one for #[cfg(windows)].
The one for not(windows) is almost be unchanged.
The windows config uses tokio::signal::windows, instead of signal_hook
Let me know how I can improve this.
Other bugs
- When pressing a key to write, it is doubled.
- If I start the
cargo runon my PC, and open chrome and go to the site universal-connectivity.on-fleek.app the two instances do not recognize/connect to each other. (If I've understood correctly this should not be the case)
Changed src/ui/headless.rs file
#![allow(dead_code)]
use crate::{log::Message as LogMessage, ChatPeer, Message, Ui};
use async_trait::async_trait;
use libp2p::core::PeerId;
use std::{collections::HashSet, time::Duration};
use tokio::sync::mpsc::{self, Receiver, Sender};
use tokio_util::sync::CancellationToken;
/// A headless UI for the peer
pub struct Headless {
// my peer id
me: ChatPeer,
// we receive log messages from the log thread
from_log: Receiver<LogMessage>,
// we send UI messages to the peer thread
to_peer: Sender<Message>,
// we receive UI messages from the peer thread
from_peer: Receiver<Message>,
// the shutdown token
shutdown: CancellationToken,
// the list of peers
peers: HashSet<ChatPeer>,
}
impl Headless {
/// Create a new UI instance
pub fn build(
me: PeerId,
from_log: Receiver<LogMessage>,
shutdown: CancellationToken,
) -> (Box<dyn Ui + Send>, Sender<Message>, Receiver<Message>) {
// create a new channels for sending/receiving messages
let (to_peer, from_ui) = mpsc::channel::<Message>(64);
let (to_ui, from_peer) = mpsc::channel::<Message>(64);
// create a new TUI instance
let ui: Box<dyn Ui> = Box::new(Self {
me: me.into(),
from_log,
to_peer,
from_peer,
shutdown,
peers: HashSet::new(),
});
(ui, to_ui, from_ui)
}
}
#[async_trait]
impl Ui for Headless {
/// Run the UI
async fn run(&mut self) -> anyhow::Result<()> {
let mut signal_handle = None;
#[cfg(not(windows))]
{
use signal_hook::{consts::SIGTERM, iterator::Signals};
// Register the SIGTERM signal
signal_handle = Some(Signals::new([SIGTERM])?);
}
#[cfg(windows)]
{
use tokio::signal::windows::{ctrl_c, ctrl_break, ctrl_close, ctrl_logoff, ctrl_shutdown};
let mut ctrl_c_signal = ctrl_c()?;
let mut ctrl_break_signal = ctrl_break()?;
let mut ctrl_close_signal = ctrl_close()?;
let mut ctrl_logoff_signal = ctrl_logoff()?;
let mut ctrl_shutdown_signal = ctrl_shutdown()?;
signal_handle = Some(tokio::spawn(async move {
tokio::select! {
_ = ctrl_c_signal.recv() => {
println!("Received Ctrl+C signal.");
}
_ = ctrl_break_signal.recv() => {
println!("Received Ctrl+Break signal.");
}
_ = ctrl_close_signal.recv() => {
println!("Received Ctrl+Close signal.");
}
_ = ctrl_logoff_signal.recv() => {
println!("Received Ctrl+Logoff signal.");
}
_ = ctrl_shutdown_signal.recv() => {
println!("Received Ctrl+Shutdown signal.");
}
}
}));
}
println!("Headless UI started");
println!("Press Ctrl+C to exit");
println!("My peer id: {} ({})", self.me.id(), self.me);
// Main loop
'main: loop {
// Process log messages
if let Ok(log) = self.from_log.try_recv() {
//TODO: remove this after [PR 5966](https://github.com/libp2p/rust-libp2p/pull/5966)
if !log.message.starts_with("Can't send data channel") {
println!("{}", log.message);
}
}
// Process peer messages
if let Ok(ui_message) = self.from_peer.try_recv() {
match ui_message {
Message::Chat { from, data } => {
let from = from.map_or("Unknown".to_string(), |peer| peer.to_string());
let message =
String::from_utf8(data).unwrap_or("Invalid UTF-8".to_string());
println!("{}: {}", from, message);
}
Message::AddPeer(peer) => {
if self.peers.insert(peer) {
println!(
"Adding peer:\n\tpeer id: {}\n\tname: {}",
peer.id(),
peer.name()
);
}
}
Message::RemovePeer(peer) => {
if self.peers.remove(&peer) {
println!("Removing peer: {peer:?}");
}
}
Message::Event(event) => {
println!("{}", event);
}
_ => {}
}
}
// check if we have received the shutdown signal from the OS
#[cfg(not(windows))]
{
let signals = signal_handle.as_ref().unwrap();
if signals.pending().next() == Some(SIGTERM) {
println!("Received SIGTERM, shutting down");
self.shutdown.cancel();
break 'main;
}
}
#[cfg(windows)]
{
let handle = signal_handle.as_ref().unwrap();
if handle.is_finished() {
println!("Received SIGTERM, shutting down");
self.shutdown.cancel();
break 'main;
}
}
tokio::time::sleep(Duration::from_millis(18)).await;
}
Ok(())
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/ui/headless.rs and reproduce cargo run on Windows, focusing first on the platform-specific signal setup in Ui::run. Then check the reported doubled key input and whether the native and browser instances connect as expected. Done means the Windows peer runs and shuts down correctly, input is not duplicated, and the two instances connect when that is the intended behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, networking, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100