// // Created by yangbin on 2021/11/15. // #include #include #include #include #include "message_channel_plugin.h" const auto kClientChannelName = "webview_message/client_channel"; namespace { using FlutterMethodChannel = std::shared_ptr>; class ClientMessageChannelPlugin { public: explicit ClientMessageChannelPlugin(FlutterMethodChannel channel); void InvokeMethod( const std::string &method, std::unique_ptr arguments) { channel_->InvokeMethod(method, std::move(arguments), nullptr); } private: FlutterMethodChannel channel_; }; class ServerMessageChannelPlugin { public: void AddClient(std::shared_ptr client) { client_set_.insert(std::move(client)); } void RemoveClient(const std::shared_ptr &client) { client_set_.erase(client); } void DispatchMethodCall( const flutter::MethodCall &call, ClientMessageChannelPlugin *client_from); private: std::set> client_set_; }; std::shared_ptr g_server_channel_plugin; class ClientPluginProxy : public flutter::Plugin { public: explicit ClientPluginProxy(std::shared_ptr client) : client_(std::move(client)) { assert(g_server_channel_plugin); g_server_channel_plugin->AddClient(client_); } ~ClientPluginProxy() override { g_server_channel_plugin->RemoveClient(client_); } private: std::shared_ptr client_; }; } void RegisterClientMessageChannelPlugin(FlutterDesktopPluginRegistrarRef registrar) { auto registrar_windows = flutter::PluginRegistrarManager::GetInstance() ->GetRegistrar(registrar); auto channel = std::make_shared>( registrar_windows->messenger(), kClientChannelName, &flutter::StandardMethodCodec::GetInstance()); if (!g_server_channel_plugin) { g_server_channel_plugin = std::make_shared(); } assert(g_server_channel_plugin); auto client_plugin = std::make_shared(channel); registrar_windows->AddPlugin(std::make_unique(client_plugin)); } ClientMessageChannelPlugin::ClientMessageChannelPlugin( FlutterMethodChannel channel ) : channel_(std::move(channel)) { channel_->SetMethodCallHandler([this](const auto &call, auto result) { if (g_server_channel_plugin) { g_server_channel_plugin->DispatchMethodCall(call, this); result->Success(); } }); } void ServerMessageChannelPlugin::DispatchMethodCall( const flutter::MethodCall<> &call, ClientMessageChannelPlugin *client_from) { for (const auto &item: client_set_) { if (item.get() != client_from) { item->InvokeMethod( call.method_name(), std::make_unique(*call.arguments())); } } }