2016-04-11 20 views
1

Web'de port C++ projesi için emscripten kullanıyorum ve C++ kodumla etkileşime girecek olan web uygulaması NodeJs üzerindeyim.Bir javascript kütüphanesi kullanarak emscripten ile Socket.io nasıl kullanılır?

Yani, Node.js üzerinde Socket.io kullanıyorum ve ben de benim C++ kodumla kullanmak istiyorum, bu yüzden socket.io kodunu kullanan bir javascript kütüphanesi kullanarak gittim, ancak görünmüyor iş.

#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 
#include <emscripten.h> 

int val = 0; 

extern "C" 
{ 
    extern void send_board(char* flat_board); 
    extern bool receive_board(char** _string_dest); 
} 

void one_iter() 
{ 
    #ifdef SEND 
    char* c = "test"; 

    std::cout << val << std::endl; 

    if(val%1000 == 0){ 
     send_board(c); 
    } 
    val++; 
    #else 
    char* c; 
    if(receive_board(&c)) std::cout << "Received:" << c << std::endl; 
    #endif 
} 


int main() 
{ 
    emscripten_set_main_loop(one_iter, 0, 1); 
    return 0; 
} 

ve

mergeInto(LibraryManager.library, { 
     send_board: function(message) { 
     socket.on('connect', function(){ 
      socket.emit('game_request_sender_pipeline', { 
       message: "Hi", 
      }); 
     }); 
     }, 

     receive_board: function(_string_dest_in_c){ 

     socket.on('connect', function(){ 
      socket.on('game_request_receiver_pipeline' , function (message) 
      { 
       var msg = "Other side : " + message.message; 
       var buffer = Module._malloc(message.message.length + 1); 
       Module.writeStringToMemory(msg, buffer); 
       setValue(_string_dest_in_c, buffer, '*'); 
       return true; 
      }); 
     }); 

     return false; 
     }, 
    }); 

ve aşağıdaki ile derlenmiş:

Bu davayı gösteren bu küçük örnek yazdım

// for the sending test 
em++ main.cpp --js-library path_to_js_library.js -o socket.html -DSEND=1 
// for the receiving test 
em++ main.cpp --js-library path_to_js_library.js -o socket.html 

ve node.js sunucu kodunda

, Ben var:

io.on('connection', function (socket) { 

     socket.on('game_request_sender_pipeline' , function (message) 
     {  
      console.log("game_request_sender_pipeline on."); 
      socket.broadcast.emit('game_request_receiver_pipeline', { 
       message: message.message, 
      }); 
      console.log("game_request_receiver_pipeline emitted."); 
     }); 
}); 

Sonuç oldukça garip, işe yaramadığını düşünmüştüm, nodejs sunucusunu iptal ettim ve yeniden başlattım ve sonuçta tarayıcıların konsolunda ortaya çıktı.

+0

'one_iter() esinlenerek' receive_board' uyumsuz görünüyor 'senkron, ama olmaz. – zakki

+0

Geri aramaları, asenkronize doğası için geçici çözümlere uygulamalı mıyım? –

+0

Sanırım so.'emscripten_set_main_loop'nun 3. parametresi true, one_iter birçok kez çağrıldı. – zakki

cevap

2

Yorumdaki önerilerin kendileri için anlamlı olduğu görülüyor.

emscripten_set_main_loop Bunun yerine return ifadeleri kullanmak yerine, sorunu çözmek için ancak javascript api gelen çağrılar nedeniyle socket.io

için asenkron olan bir senkron davranışını simüle ve koşullu bunu ister want- kodunu uygulayarak doğru ya da yanlış olsun - geri aramaları kullanmayı düşündüm.

fikri şöyledir: Ana döngüde

  1. , orada receive_board yapılan bir çağrı olacak.
  2. receive_board, bir başarı geri çağrısı ve bir hata olarak geri çağırma parametresi alır. (Geri aramalar C işlevidir) Module.ccall kullanarak geri aramaları c'den arayalım.
  3. geri aramalar aslında bu anahtar kelimeyi yazmaya önlemek için ben, biz, fonksiyon tanımında anahtar kelime EMSCRIPTEN_KEEPALIVE kullanmak zorunda olacak ccall kullanmak için ve sırayla alındığı

üzerine şartlı yürütmek istediği kod içeren Tanımlanacak her geri çağrı için, sadece geri aramaları çağıran tek bir işlev için kullanmaya karar verdim.

extern "C" 
{ 
EMSCRIPTEN_KEEPALIVE void callback_invoker(void* fn_ptr, void* fn_arg) 
{ 
    // some kind of cast to the original function signature, and to the original fn_arg type 
    (*fn_ptr)(fn_arg); 
} 
} 

Ve javascript tarafında

mergeInto(LibraryManager.library, { 
     receive_board: function(_string_dest_in_c, succcess_callback, failure_callback, s_cb_arg, f_cb_arg){ 

     socket.on('connect', function(){ 
      socket.on('game_request_receiver_pipeline' , function (message) 
      { 
       var msg = "Other side : " + message.message; 
       var buffer = Module._malloc(message.message.length + 1); 
       Module.writeStringToMemory(msg, buffer); 
       setValue(_string_dest_in_c, buffer, '*'); 
       Module.ccal('callback_invoker', 'void', ['number', 'number'], [success_callback, s_cb_arg]); 
       return; 
      }); 
     }); 

     Module.ccal('callback_invoker', 'void', ['number', 'number'], [failure_callback, f_cb_arg]); 
     }, 
    }); 

Bu şekilde içinde

, ben yukarıda belirtilen sorun çözüldü.

bu answer

+0

Çok akıllı bir çözüm; JS tarafında dinamik olarak bellek ayırmayı düşünmedim! – Ameo

İlgili konular