2017-06-19 389 views

回答

4

示例代碼連接到公共回聲Web套接字服務器, 發送消息,接收響應並斷開連接。

JavaScript代碼提供web套接字和日誌記錄到webassembly代碼的功能。

主程序邏輯用C編寫,然後編譯成wasm文件。

結果可以在js控制檯中看到。

彙編:

EMCC ws_test.c -o ws_test.html -O1 -s WASM = 1 -s ONLY_MY_CODE = 1 -s EXPORTED_FUNCTIONS =「[ '_的GetBuffer', '_ wsOnMessage', '_wsOnOpen', '_test']「

結果文件ws_test.wasm很小。 (431個字節)

要檢查WASM可以被反編譯到可讀s表達式的條件:
wasm2wast ws_test.wasm -o ws_test.wast

ws_test.c

extern void wsConnect(char *address); 
    extern void wsSend(char *message); 
    extern void wsClose(); 
    extern void print(char *message); 

    char buffer[100]; 
    char *getBuffer(){ return buffer; } 

    void wsOnMessage(){ 
     print("received message"); 
     print(buffer); 
     wsClose(); 
     print("connection closed"); 
    } 

    void wsOnOpen(){ 
     print("connected"); 
     wsSend("Hello WebAssembly !"); 
    } 


    void test(){ 
     wsConnect("ws://echo.websocket.org"); 
     print("connecting..."); 
    } 

ws_test.html

 <script> 

     var webSocket; 
     const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }); 
     const buffer = new Uint8Array(memory.buffer); 
     var exports; 

     function toJsStr(offset){ 
      var s=""; 
      for(;;){ 
       var b = buffer[offset++]; 
       if(b == 0) 
        return s; 
      s += String.fromCharCode(b); 
     } 
     } 
     function toCStr(str){ 
     var offset = exports._getBuffer(); 
     for (var i = 0; i < str.length; ++i) { 
      buffer[offset++] = str.charCodeAt(i); 
     } 
     buffer[offset] = 0; 
     } 

     function print(offset){ 
     console.log(toJsStr(offset)); 
     } 

     function wsConnect(offset){ 
     webSocket = new WebSocket(toJsStr(offset)); 
     webSocket.onopen = function(){ 
      console.log("Socket is open"); 
      exports._wsOnOpen(); 
     }; 

     webSocket.onmessage = function (evt){ 
      var msg = evt.data; 
      console.log("Message is received..."); 
      toCStr(msg); 
      exports._wsOnMessage(); 
     }; 
     } 

     function wsClose(){ 
     webSocket.close(); 
     } 

     function wsSend(offset){ 
     webSocket.send(toJsStr(offset)); 
     } 

     fetch('ws_test.wasm').then(response => 
     response.arrayBuffer() 
    ).then(bytes => { 
      var imports = {}; 
      imports.env = {}; 
      imports.env.memory = memory; 
      imports.env.memoryBase = 0; 
      imports.env.table = new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' }); 
      imports.env.tableBase = 0; 
      imports.env._print = print; 
      imports.env._wsConnect = wsConnect; 
      imports.env._wsSend = wsSend; 
      imports.env._wsClose = wsClose; 


      return WebAssembly.instantiate(bytes, imports); 
     } 
    ).then(module => { 
      exports = module.instance.exports; 

      exports._test(); 
      } 
    ); 
     </script> 

在這裏使用的編譯器標記「ONLY_MY_CODE = 1」,所以結果WASM將非常小, 和不鏈接到任何標準庫

如果模塊用於算術計算該模式是方便的。

所以你不能在模式下使用:printf,malloc/free,strcpy!

如果您錯過了字符串函數:strcpy,strcat,strlen ... - 您可以將函數源添加到代碼中。

但是,如果你需要例如malloc/free更好的鏈接標準C庫。

0

它只是演示,而不是產品。

  • toJsStr(偏移量)和toCStr(STR)可以支持UTF-8(目前僅ASCII)

  • toCStr應該使用不僅緩衝區偏移,而且緩衝區大小,以防止 緩衝區溢出。

  • 錯過的通訊錯誤處理:應使用web套接字回調: 的onerror()的OnClose()