# Communication API The following JavaScript functions are used for for communicating data between various SimConnect clients, WebAssembly modules, and JavaScript gauges. You can find information on the other platform communication functions from the following pages: - [SimConnect Communication API](../../simconnect/api-reference/communication/communication-api/) - [WebAssembly Communication API](../../wasm/communication-api/communication-api/) When using this API it's worth noting the following: - JSON is a good way to format data for communication between the different platforms. In C++, a version of [RapidJSON](https://rapidjson.org/) is provided as part of the SDK - with some fixes to work in Web Assembly - and can help you when sharing information. - You can add an ID in function arguments to know the caller, and ensure you are dealing with the correct events. - All calls are asynchronous.   You can find a sample project to use as a reference when using the Communication API here: - [CommBusAircraft](../../../samples-tutorials/samples/simobjects-aircraft/modularaircraft/commbusaircraft/) There are also debugging tools available in DevMode which can be used to help debug Flow Events and Communication API events, which are described on the following page: - [Debug Platform Dispatcher](../../../devmode/menus/debug_info/debug-platform-dispatcher/) ### Functions The functions and methods listed below are available by including the `CommBus.js` file: ``` js Include.addScript("/JS/Services/CommBus.js"); ``` #### RegisterCommBusListener This function is used to register the communication (CommBus) event listener. ``` js function RegisterCommBusListener(callback?: any): CommBusListener; ``` {{< table-wrapper >}} | Parameter | Description | |------------|--------------------------------------------------------------------| | `callback` | An optional callback called when the listener has been registered. | {{< /table-wrapper >}} ##### Return A CommBusListener object. #### CommBusListener::callWasm This function is used to call a communication (CommBus) event on WASM modules. ``` js CommBusListener::callWasm(name: string, jsonBuf: string): Promise; ``` {{< table-wrapper >}} | Parameter | Description | |-----------|--------------------------------------------------------------------------------------------------------------------------------| | `name` | The name of the event to call. | | `jsonBuf` | A buffer of data sent along side the event. Formatting the buffer as JSON is a good way to send data, but it is not mandatory. | {{< /table-wrapper >}} ##### Return A [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) about the completion of the call operation. #### CommBusListener::callSimConnect This function is used to call a communication (CommBus) event on SimConnect clients. ``` js CommBusListener::callSimConnect(name: string, jsonBuf: string): Promise; ``` {{< table-wrapper >}} | Parameter | Description | |-----------|--------------------------------------------------------------------------------------------------------------------------------| | `name` | The name of the event to call. | | `jsonBuf` | A buffer of data sent along side the event. Formatting the buffer as JSON is a good way to send data, but it is not mandatory. | {{< /table-wrapper >}} ##### Return A [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) about the completion of the call operation. #### CommBusListener::callAll This function is used to call a communication (CommBus) event on both WASM modules and SimConnect clients. ``` js CommBusListener::callAll(name: string, jsonBuf: string): Promise; ``` {{< table-wrapper >}} | Parameter | Description | |-----------|--------------------------------------------------------------------------------------------------------------------------------| | `name` | The name of the event to call. | | `jsonBuf` | A buffer of data sent along side the event. Formatting the buffer as JSON is a good way to send data, but it is not mandatory. | {{< /table-wrapper >}} ##### Return A [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) about the completion of the call operation. ### Calling And Registering Events The communication (CommBus) API is cross platform, and as such, can be used to call *and* register events on the different supported platforms. Below you can find brief overviews for how this can be done, per-platform. #### Register An Event Using JavaScript Create a JS callback: ``` js myJsCallback(args) { ... } ``` Register the view listener: ``` js this.wasmListener = RegisterCommBusListener(); ``` Register the callback on the event: ``` js this.wasmListener.on("MyJsCallback", this.myJsCallback); ``` #### Call A WASM Event From JS In the WASM module you would create your callback: ``` cpp static void MyWasmCallback(const char* args, unsigned int size, void* ctx) { ... } ``` Then you would register the callback: ``` cpp fsCommBusRegister("MyWasmCallback", MyWasmCallback); ``` It is possible to add a pointer to a context. This pointer will be retrieved in the callback in the `ctx` argument: ``` cpp void* ctx = something; fsCommBusRegister("MyWasmCallback", MyWasmCallback, ctx); ``` Register your listener in the JavaScript: ``` js this.commBusListener = RegisterCommBusListener(); ``` Then call the WASM event using either of the following in the JS methods: ``` js // Using the communications API this.commBusListener.callWasm("MyWasmCallback", "{value : 42}"); // Using Coherent Coherent.call("COMM_BUS_WASM_CALLBACK", "MyWasmCallback", "{value : 42}"); this.wasmListener.call("COMM_BUS_WASM_CALLBACK", "MyWasmCallback", "{value : 42}"); ``` #### Call A SimConnect (c++/c#) Event From JS {{< tabs/container "C++" "C#" >}} {{< tabs/content >}} In SimConnect, connect a client and call a dispatch proc: ``` cpp #include "SimConnect.h" HANDLE hSimConnect = NULL; void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) { // Dispacth } int main() { SimConnect_Open(&hSimConnect, "CommBus client", NULL, 0, 0, 0)); // Setup while (1) { SimConnect_CallDispatch(hSimConnect, MyDispatchProcSO, NULL); Sleep(1); } return 0; } ``` Declare an event enum: ``` cpp enum EVENTS { CommBusEvent, } ``` Subscribe to a CommBus event by calling `SimConnect_SubscribeToCommBusEvent` (in the above code this can be added at the `//Setup` comment): ``` cpp SimConnect_SubscribeToCommBusEvent(hSimConnect, EVENTS::CommBusEvent, "MyCommBusEvent"); ``` In the `DispatchProc` process the event: ``` cpp std::string str; void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) { switch (pData->dwID) { case SIMCONNECT_RECV_ID_COMM_BUS: // The received data comes from a comm bus event { SIMCONNECT_RECV_COMM_BUS* pCommBusEvt = (SIMCONNECT_RECV_COMM_BUS*)pData; switch (pCommBusEvt->uEventID) // Check which event this is { case EVENT_COMM_BUS: { if (pCommBusEvt->dwOutOf == 1) { PrintReceivedData(pCommBusEvt->rgData); } else { receptionBuffer += data.rgData; if (pCommBusEvt->dwEntryNumber + 1 == pCommBusEvt->dwOutOf) { PrintReceivedData(receptionBuffer); receptionBuffer = ""; } } break; } } } } } ``` Register your listener in the JavaScript: ``` js this.commBusListener = RegisterCommBusListener(); ``` Then call the SimConnect event using the following in the JS file: ``` js this.commBusListener.callSimConnect("MyCommBusEvent", "{value : 42}"); ``` {{< /tabs/content >}} {{< tabs/content >}} In SimConnect (C\#), open a connection: ``` cs SimConnect m_oSimConnect = new SimConnect("Connection name", m_hWnd, WM_USER_SIMCONNECT, null, 0); ``` Create a CommBus callback: ``` cs string receptionBuffer; void OnCommBusEvent(SimConnect sender, SIMCONNECT_RECV_COMM_BUS data) { switch (data.uEventID) { case ((int)Events.CommBusEvent): { if (data.dwOutOf == 1) { PrintReceivedData(data.rgData); } else { receptionBuffer += data.rgData; if (data.dwEntryNumber + 1 == data.dwOutOf) { PrintReceivedData(receptionBuffer); receptionBuffer = ""; } } } break; default: break; } } ``` Register a callback on Recv CommBus: ``` cs m_oSimConnect.OnRecvCommBus += new SimConnect.RecvCommBusEventHandler(OnCommBusEvent); ``` Register the event: ``` cs m_oSimConnect.SubscribeToCommBusEvent(Events.CommBusEvent, "SimConnectEventName"); ``` Register your listener in the JavaScript: ``` js this.commBusListener = RegisterCommBusListener(); ``` Then call the SimConnect (C\#) event using the following in the JS file: ``` js this.commBusListener.callSimConnect("SimConnectEventName", "{value : 42}"); ``` {{< /tabs/content >}} {{< /tabs/container >}} ### Known Issues When the simulation is paused, WebAssembly modules and SimConnect clients are still updated. However **this is not the case for JavaScript gauges**. Therefore, events sent to JS from WASM/SimConnect will be queued *but not processed until the simulation is unpaused*. When the simulation is unpaused all queued events will be processed in the order that they were received, which *may* lead to a freeze if there are multiple events in the queue. It is the responsibility of the developer to handle this gracefully and try and prevent a build up of events when paused.