Skip to content

Commit

Permalink
Made rpc more robust.
Browse files Browse the repository at this point in the history
  • Loading branch information
5cript committed Nov 17, 2023
1 parent d9e7b80 commit 88949b4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
3 changes: 3 additions & 0 deletions nui/include/nui/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ namespace Nui

/// WEBKIT ONLY (Linux & Mac)
std::optional<std::string> folderMappingScheme = std::string{"assets"};

// Called when a message from the view cannot be parsed or references an invalid function or has no id.
std::function<void(std::string_view)> onRpcError = {};
};
#else
struct WindowOptions
Expand Down
44 changes: 39 additions & 5 deletions nui/src/nui/backend/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <list>
#include <array>
#include <string>
#include <iostream>

#ifndef _WIN32
namespace Nui
Expand Down Expand Up @@ -98,9 +99,9 @@ namespace Nui
# include "mac_webview_config_from_window_options.ipp"
#elif defined(_WIN32)
# include <webview2_environment_options.hpp>
#ifndef _MSC_VER
# include <webview2_iids.h>
#endif
# ifndef _MSC_VER
# include <webview2_iids.h>
# endif
# include <wrl/event.h>
# include "environment_options_from_window_options.ipp"
constexpr static auto wakeUpMessage = WM_APP + 1;
Expand All @@ -120,6 +121,7 @@ namespace Nui
std::recursive_mutex viewGuard;
int width;
int height;
std::function<void(std::string_view)> onRpcError;

virtual void registerSchemeHandlers(WindowOptions const& options) = 0;

Expand All @@ -131,6 +133,7 @@ namespace Nui
, viewGuard{}
, width{0}
, height{0}
, onRpcError{}
{}
virtual ~Implementation()
{
Expand Down Expand Up @@ -202,6 +205,15 @@ namespace Nui
: impl_{std::make_shared<WindowsImplementation>()}
#endif
{
if (!options.onRpcError)
{
impl_->onRpcError = [](std::string_view msg) {
std::cerr << "NUI RPC Error: " << msg << std::endl;
};
}
else
impl_->onRpcError = options.onRpcError;

#ifdef __APPLE__
impl_->initialize(
options.debug,
Expand All @@ -215,8 +227,27 @@ namespace Nui

impl_->view->install_message_hook([this](std::string const& msg) {
std::scoped_lock lock{impl_->viewGuard};
const auto obj = nlohmann::json::parse(msg);
impl_->callbacks[obj["id"].get<std::string>()](obj["args"]);
try
{
const auto obj = nlohmann::json::parse(msg);
if (!obj.contains("id"))
return impl_->onRpcError("Message does not contain a callback id!"), false;

const auto id = obj["id"].get<std::string>();
auto callbackIter = impl_->callbacks.find(id);
if (callbackIter == impl_->callbacks.end())
return impl_->onRpcError("Callback with id " + id + " does not exist!"), false;

if (!obj.contains("args"))
callbackIter->second(nlohmann::json{});
else
callbackIter->second(obj["args"]);
}
catch (std::exception const& exc)
{
impl_->onRpcError(
"Exception in webview message handler for message: " + msg + "\nException: " + exc.what());
}
return false;
});

Expand Down Expand Up @@ -481,6 +512,9 @@ namespace Nui
//---------------------------------------------------------------------------------------------------------------------
void Window::bind(std::string const& name, std::function<void(nlohmann::json const&)> const& callback)
{
if (!callback)
throw std::runtime_error("Callback must be valid.");

runInJavascriptThread([this, name, callback]() {
std::scoped_lock lock{impl_->viewGuard};
impl_->callbacks[name] = callback;
Expand Down

0 comments on commit 88949b4

Please sign in to comment.