這幾點很大程度上體現出了node和deno在設計本質上的區別,同時這幾點體現了deno的安全性(利用 JavaScript 自己即爲安全沙箱這一事實)java
從圖中能夠清晰的看出,V8worker2是v8和Go之間實現調用的核心組件node
能夠看出V8worker2 是經過binding C++ 模塊進行綁定V8,bingding暴露了基礎操做方法:$v8_init() 、$worker_load()、$worker_send_bytes()、$worker_dispose()...提供給GO 進行調用git
//binding.h const char* worker_version(); void worker_set_flags(int* argc, char** argv); void v8_init(); worker* worker_new(int table_index); int worker_load(worker* w, char* name_s, char* source_s); const char* worker_last_exception(worker* w); int worker_send_bytes(worker* w, void* data, size_t len); void worker_dispose(worker* w); void worker_terminate_execution(worker* w);
經過Golang的GC提供的CGO模塊調用C語言暴露的方法,就能夠實現GO和V8之間的通訊了:github
// worker.go package v8worker2 import "C" ... func recvCb(buf unsafe.Pointer, buflen C.int, index workerTableIndex) C.buf { ... } func New(cb ReceiveMessageCallback) *Worker { ... initV8Once.Do(func() { C.v8_init() }) } func (w *Worker) Load(scriptName string, code string) error { ... r := C.worker_load(w.worker.cWorker, scriptName_s, code_s) ... } func (w *Worker) SendBytes(msg []byte) error { ... r := C.worker_send_bytes(w.worker.cWorker, msg_p, C.size_t(len(msg))) }
// hello.go package main import ( "fmt" "github.com/ry/v8worker2" ) func main() { worker := v8worker2.New(recv) // 實現JS的console.log 方法 err := worker.Load("hello.js", ` this["console"] = { log(...args) { V8Worker2.print(args) } }; console.log("Hello World"); `) if err != nil { fmt.Println(err) } // 發送數據給GO err = worker.Load("sendData.js", ` V8Worker2.send(new ArrayBuffer(5)) `) if err != nil { fmt.Println(err) } // 發送數據給JS err = worker.Load("recvData.js", ` V8Worker2.recv(function(msg) { const len =msg.byteLength; console.log("recv data from go,length: "+len); }); `) if err != nil { fmt.Println(err) } err = worker.SendBytes([]byte("abcd")) } func recv(buf []byte) []byte { fmt.Println("recv data from js,length:", len(buf)) return nil }
在控制檯運行: go run hello.go
安全
須要運行測試代碼,能夠直接訪問個人github :deno 案例源碼架構
參考資料函數