2017-07-21 11 views
10

RustからWebワーカーを作成しようとしています。ワーカーファイルで関数を呼び出し、メインスレッドにデータを渡しています。RustからEmscriptenターゲットを使用してWebワーカーを作成する

main.rs

mod externs; 
extern crate libc; 

fn main() { 
    println!("starting worker"); 
    let worker = externs::create_worker("./worker.js"); 
    externs::call_worker(worker, "worker_fn", "", 0); 
    println!("worker called"); 
} 

worker.rs

#![feature(link_args)] 
#[link_args = "-s EXPORTED_FUNCTIONS=['_worker_fn'] -s BUILD_AS_WORKER=1"] 

extern crate libc; 

mod externs; 

extern {} 

fn main() { 
    println!("worker main"); 
} 

#[no_mangle] 
pub extern fn worker_fn() { 
    println!("hello from the other side!"); 
} 

私は労働者と主なファイルをコンパイル、私もmain.rsからのメッセージを見ることができますよワーカーファイル内の「ワーカーメイン」メッセージ。私はまた、ブラウザがworker.jsに要求を送信するのを見ることができますが、メインスレッドがワーカーファイル内のworker_fnを呼び出さないようです。

これはexternsファイルです:私は問題が何であるかを理解していない

use std::ffi::CString; 
use libc::*; 
use std::str::FromStr; 

/// Creating web worker 
pub fn create_worker(url: &str) -> ffi::worker_handle { 
    let url = CString::new(url).unwrap(); 
    let ptr = url.as_ptr(); 
    unsafe { ffi::emscripten_create_worker(ptr) } 
} 

extern "C" fn do_something_handler(arg1: *mut c_char, arg2: c_int, arg3: *mut c_void) { 
    println!("worker done!"); 
} 

/// Creating web worker 
pub fn call_worker(worker: ffi::worker_handle, func_name: &str, data: &str, size: i32) { 
    let func_name = CString::new(func_name).unwrap(); 

    let mut string = String::from_str(data).unwrap(); 
    let bytes = string.into_bytes(); 
    let mut cchar : Vec<c_char> = bytes.iter().map(|&w| w as c_char).collect(); 
    let data_slice = cchar.as_mut_slice(); 

    let mut state = 42; 
    let state_ptr: *mut c_void = &mut state as *mut _ as *mut c_void; 

    unsafe { 
     ffi::emscripten_call_worker(
      worker, 
      func_name.as_ptr(), 
      data_slice.as_mut_ptr(), 
      size as c_int, 
      Some(do_something_handler), 
      state_ptr 
     ) 
    }; 
} 

// This is mostly standard Rust-C FFI stuff. 
mod ffi { 
    use libc::*; 
    pub type worker_handle = c_int; 
    pub type em_worker_callback_func = Option<unsafe extern "C" fn(arg1: *mut c_char, 
                    arg2: c_int, 
                    arg3: *mut c_void)>; 

    extern "C" { 
     pub fn emscripten_run_script_int(x: *const c_char) -> c_int; 
     pub fn emscripten_create_worker(url: *const c_char) -> worker_handle; 
     pub fn emscripten_call_worker(
      worker: worker_handle, 
      funcname: *const c_char, 
      data: *mut c_char, 
      size: c_int, 
      callback: em_worker_callback_func, 
      arg: *mut c_void 
     ); 
     pub fn emscripten_worker_respond(data: *mut c_char, size: c_int); 
     pub fn emscripten_worker_respond_provisionally(data: *mut c_char, size: c_int); 
    } 
} 

。私はどういうわけかワーカーファイルを変更するか、あるいはlink_argsを変更する必要がありますか? 、

worker.rs

#![feature(link_args)] 
#[link_args = "-s BUILD_AS_WORKER=1"] 

#[macro_use] 
extern crate stdweb; 

fn main(){ 
    stdweb::initialize(); 

    js! { 
     this.addEventListener("message", (e) => { 
      console.log("The main thread said something", e.data); 
     }) 
    } 
    stdweb::event_loop(); 
} 

loader.js

var wasm_file = "worker.wasm"; // wasm file 
var wjs_file = "worker.js"; // w.js file that links the wasm file 

Module = {} 
console.log("Loading webassembly version"); 
/// fetch wasm file and inject the js file 
fetch(wasm_file) 
    .then(response => response.arrayBuffer()) 
    .then(bytes => { 
    Module.wasmBinary = bytes; 
    console.log("wasm has loaded.."); 
    console.log("attaching as script"); 
    self.importScripts(wjs_file); 
    }); 

し、最終的に:

答えて

4

は、私はこのようなstdwebクレート(感謝ivanceras)を使用して問題を修正しましたHTMLファイル

<script> 
    var worker = new Worker("loader.js"); 
    setTimeout(function() { 
     worker.postMessage({"cmd":"doSomething"}); 
    }, 1000); 
</script> 

は、あなたが錆ファイルをビルドするとき--target=wasm32-unknown-emscriptenフラグを追加することを忘れないでください。

+0

「worker.js」が必要な理由を理解してください。 'loader.js'が' Worker'内で実行されると、wasmファイルを直接読み込むのはなぜですか?代わりに 'importScripts'を使用して、wasmファイルをロードするはずの' worker.js'に渡します。なぜこの間接の層が増えるのでしょうか? –

関連する問題