2017-07-21 9 views
10

मैं जंग से एक वेब कार्यकर्ता बनाने, कार्यकर्ता फ़ाइल में एक फ़ंक्शन को कॉल करने और मुख्य डेटा को कुछ डेटा पास करने का प्रयास कर रहा हूं।ईस्टस्क्रिप्ट लक्ष्य के साथ जंग से वेब कार्यकर्ता बनाना

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 पर कॉल नहीं करता है।

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); 
    } 
} 

मुझे समझ नहीं आता कि समस्या क्या है:

यह externs फ़ाइल है। क्या मुझे किसी भी तरह से कार्यकर्ता फ़ाइल या शायद 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) का उपयोग करके समस्या तय एचटीएमएल फाइल:

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

--target=wasm32-unknown-emscripten फ्लैग जोड़ने के लिए जब आप जंग फ़ाइल का निर्माण मत भूलना।

+0

मुझे समझने में सहायता करें कि 'worker.js' क्यों आवश्यक है। यदि 'वर्कर' के भीतर 'loader.js' चलाया जाता है, तो यह केवल वैसे ही फ़ाइल को लोड क्यों नहीं करता है? इसके बजाय यह 'importScripts' का उपयोग 'worker.js' को सौंपने के लिए करता है जो कि wasm फ़ाइल को लोड करना है। संकेत की यह अतिरिक्त परत क्यों? –

संबंधित मुद्दे