Communication Between WinForms Application And Web Application Using CefSharp Browser Event

Introduction

Hello Friends!!!! In this article, I am going to explain how to pass data from a WinForms application to a Web application (ReactJS) and vice versa using CefSharp browser events. CefSharp browser is Chromium-based browser control for WinForms and WPF applications. CefSharp is a .NET wrapper around the Chromium Embedded Framework and it is open source. 

Demo

Simple Chat application

There are two applications,

  1. WinForm application (.NET Framework 4.7.2)
  2. ReactJS application

WinForm Application

Create a new WinForm application.

Communication Between WinForms Application And Web Application Using CefSharp Browser Event

Add CefSharp.WinForms package using Nuget manager,

Communication Between WinForms Application And Web Application Using CefSharp Browser Event

Create the "Message.cs" class and create a model for data.

public class Message
{
    [JsonProperty("data")]
    public object Data { get; set; }
}

Create a simple form as below,

Communication Between WinForms Application And Web Application Using CefSharp Browser Event

Add code to create CefSharp browser. 

public SampleForm()
{
    InitializeComponent();

    AddBrowserControl();
}

private void AddBrowserControl()
{
    browser = new ChromiumWebBrowser("http://localhost:3000");
    pnlBrowserContainer.Controls.Add(browser);
    browser.Dock = DockStyle.Fill;

    browser.JavascriptMessageReceived += OnReceiveNotification;
    browser.LoadingStateChanged += OnLoadingStateChanged;
}

Add the below method and bind it to the CefSharp event handler called "LoadingStateChanged". The method will be triggered when the web application has fully loaded in the browser control. The method is used to execute the simple javascript code. In the javascript code, attach the "CefSharp.PostMessage" handler with "messageSentEvent" type. Whenever the event is dispatched with the type "messageSentEvent" in the web application then "CefSharp.PostMessage" will be executed.

private void OnLoadingStateChanged(object sender, EventArgs e)
{
    string script = @"if(!messageSentEvent){
                                var messageSentEvent = new Event('messageSentEvent'); 
                                document.addEventListener('messageSentEvent', (message)=>{
                                    CefSharp.PostMessage(JSON.stringify(message.detail)); 
                                });
                            }";

    browser.GetMainFrame().ExecuteJavaScriptAsync(script);
}

Add below the method for receiving data from a web application and bind it to the CefSharp eventhandler called "JavascriptMessageReceived". Whenever the data has been sent from a web application, then this method will be triggered.

private void OnReceiveNotification(object sender, JavascriptMessageReceivedEventArgs e)
{
    Message message = JsonConvert.DeserializeObject<Message>((string)e.Message);

    if (rtChatHistory.InvokeRequired)
    {
        rtChatHistory.Invoke(new Action(() => rtChatHistory.AppendText("Web: " + message.Data + Environment.NewLine)));
    }
    else
    {
        rtChatHistory.AppendText("Web: " + message.Data + Environment.NewLine);
    }
}

Add below method for sending the data to the web application. The data has been sent using a simple javascript snippet that is executing in the browser frame. In the javascript code, creating a custom event with "messageReceiveEvent" type and data then dispatch the event.

private void SendNotification(Message message)
{
    string jsonMessage = SerializeMessage(message);

    string script = @" var event= new CustomEvent('messageReceiveEvent', {detail: " + jsonMessage + @"}); 
                    document.dispatchEvent(event);";

    browser.GetMainFrame().ExecuteJavaScriptAsync(script);
}

ReactJS Application

Create an empty ReactJS application. Please refer to the link to create the ReactJS application. Here, I am using JS and Hooks in my react application. 

Create EventHandler.js file and add the below code. The "SendMessageHandler" function is used to dispatch the custom event with the type is "messageSentEvent". Whenever the custom event has dispatches, the CefSharp.PostMessage will be executed (See point #6 in WinForm application) and then "JavascriptMessageReceived" eventhandler will be called (See point #7 in WinForm application).

export function SendMessageHandler(e) {
  const event = new CustomEvent("messageSentEvent", {
    detail: {
      data: e,
      type: "SendMessage"
    }
  });
  document.dispatchEvent(event);
}

Modify the App.js file with the below code. In the below code, attach the "ReceiveMesaageHandler" function with "messageReceiveEvent" type using addEventListener() method. Whenever the javascript has executed with type "messageReceiveEvent"(See point #8 in WinForm application) then "ReceiveMesaageHandler" function will be a trigger. Inside the "ReceiveMesaageHandler" function, just append the received data to the local state.

useEffect(() => {
    document.addEventListener("messageReceiveEvent", ReceiveMesaageHandler);
    return () => {
      document.removeEventListener("messageReceiveEvent", ReceiveMesaageHandler);
    };
}, []);

function ReceiveMesaageHandler(e) {
    SetChatHistory(prevChat => prevChat !== "" ? (prevChat + "\nWindows :" + e.detail.data) : ("Windows :" + e.detail.data));    
}

How to run

Run the ReactJS application using "npm run start". Here my react application is running in "http://localhost:3000". The same URL has been given in the CefSharp browser control (See the code part in point #5 of the WinForm application).

Communication Between WinForms Application And Web Application Using CefSharp Browser Event

Run the Winform application.

Communication Between WinForms Application And Web Application Using CefSharp Browser Event

  • In the WinForm application, type a message in the text box and click send button. The ReactJS application (inside the browser control) will receive the message. You can see this in the "Chat History" text box.
  • Same as above, you can send messages from the ReactJS application also.

Communication between WinForms application and Web application using CefSharp browser event

In this article, I discussed how to communicate between WinForms application and Web application using CefSharp browser event. Hope you liked it. If you have any doubts or comments about this, please let me know in the comments.