2017-07-25 11 views
0

私はrust-websocketsのasync websocketクライアントを利用して、RustのPhoenixクライアントライブラリを作成しています。今、私はwebsocketトラフィックを処理しているスレッドにコールバック関数を渡す方法を考え出すのに問題があります。私が簡略化され、構造体があります。別のスレッドからFnMutコールバックを呼び出す

pub struct Socket { 
    endpoint:    String, 
    connected:    Arc<AtomicBool>, 
    state_change_close:  Option<Box<FnMut(String)>>, 
} 

をこの構造体には、次のようにレイアウトされconnect機能を持っています

pub fn connect(&mut self) -> Result<(), String> { 
    if self.connected.load(Ordering::Relaxed) { 
     return Ok(()) 
    } 

    // Copy endpoint string, otherwise we get an error on thread::spawn 
    let connection_string = self.endpoint.clone(); 
    let (usr_msg, stdin_ch) = mpsc::channel(0); 

    let connection_thread = thread::spawn(move || { 
     // tokio core for running event loop 
     let mut core = Core::new().unwrap(); 
     let runner = ClientBuilder::new(&connection_string) 
      .unwrap() 
      .add_protocol("rust-websocket") 
      .async_connect_insecure(&core.handle()) 
      .and_then(|(duplex, _)| { 
       let (sink, stream) = duplex.split(); 
       stream.filter_map(|message| { 
        println!("Received Message: {:?}", message); 
        match message { 
         OwnedMessage::Close(e) => { 
          // This is the line where I am trying to call the callback 
          if let Some(ref mut func) = self.state_change_close { 
           (func)(e.unwrap().reason); 
          } 
          Some(OwnedMessage::Close(e)) 
         }, 
         _ => None, 
        } 
       }) 
       .select(stdin_ch.map_err(|_| WebSocketError::NoDataAvailable)) 
       .forward(sink) 
      }); 

     // Start the event loop 
     core.run(runner).unwrap(); 
    }); 
    self.connected.store(true, Ordering::Relaxed); 
    return Ok(()) 
} 

私はこのコードをコンパイルしようとすると、私は次のエラーを取得:

error[E0277]: the trait bound `std::ops::FnMut(std::string::String) + 'static: std::marker::Send` is not satisfied 
    --> src\socket.rs:99:29 
    | 
99 |  let connection_thread = thread::spawn(move || { 
    |        ^^^^^^^^^^^^^ the trait `std::marker::Send` is not implemented for `std::ops::FnMut(std::string::String) + 'static` 
    | 

state_change_closeのタイプをMutex<Option<...>>に変更しようとしましたが、スレッドの安全性の問題は発生しませんでしたが、この問題は解決しませんでした。私がしようとしていることは可能ですか?

答えて

1

さらに調査をしたところ、Option<Box<FnMut(String)>>Option<Box<FnMut(String) + Send>>に変更して、コールバックが設定されている可能性があるすべての場所に自分のコードの周りにコピーする必要があることに気付きました。特性オブジェクトの詳細を学ぶ!

関連する問題