Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javascript Binding Ready For Testing #480

Closed
amaitland opened this issue Sep 16, 2014 · 60 comments
Closed

Javascript Binding Ready For Testing #480

amaitland opened this issue Sep 16, 2014 · 60 comments
Assignees
Milestone

Comments

@amaitland
Copy link
Member

For those of you interested in Javascript Binding, I'm fairly happy with the performance and stability of https://github.com/cefsharp/CefSharp/tree/JsBinding_WIP

If your at all interested in seeing this feature in CefSharp3 please download and build the JsBinding_WIP branch and test it with your application.

  • Global Cef.RegisterJsObject has been removed, for now you have to bind using the method directly on ChromiumWebBrowser, will look at re-adding that feature later
  • Need to Register objects directly after Browser is created as there's no on the fly binding as yet
  • EvaluateScriptAsync now returns a Task<JavascriptResponse> so errors can be correctly returned from the render process
  • Complex objects are supported so you can now do bound.subObject.myFunction() and bound.subObject.myProperty = 1

Feedback required!

P.S. I'm fairly new to c++ so if you do happen to go through the code and see some mistakes, if you could provide constructive feedback that would also be welcome! 😄

@amaitland amaitland added the cef3 label Sep 16, 2014
@amaitland amaitland self-assigned this Sep 16, 2014
@amaitland amaitland added this to the 31.0.0 milestone Sep 16, 2014
@tomtorell
Copy link

Hi amaitland,

I'm just going to test this, because I exactly need this functionality: Javascript Binding in a x64 Chromium.

One little question: CefSharp3 now is multiprocess. When Javascript calls my C# function, in witch thread this will happen? In the main or in the worker (Render or Javascript) thread? What will I have to do, if this call happens in the worker thread and I need a call to the main thread from here? I'm new to threads.

@amaitland
Copy link
Member Author

@tomtorell CefSharp3 is multiprocess, so the the rendering is done in it's own process. Cef communicates using IPC between the two. For JS Binding we use WCF to communicate between the client and subprocess. For the most part you don't really need to know too much about how all this happens.

As for Threading it in itself is a broad and complex subject, so without knowing exactly what your trying to achieve I can't really provide to much detailed information.

My suggestion would be to go through the WPF or WinForms examples, write your proof of concept application and come back with any specific questions as required.

@tomtorell
Copy link

@amaitland in the first start-up Javascript Binding was successful for me. I now can call my C# functions from Javascript e.g. in the form callbackhandler.myFunction(...).

To answer my own question from above, yes myFunction is called in a worker thread, not in the main thread! So you have to be careful, if the task that should be done in myFunction can run in a worker thread. In some functions, I call a really big library and this is invalid in a worker thread. In these cases, I have to call my main thread first, otherwise my application crashes! This has changed compared to CefSharp1.

So far Javascript is working now, but I found a serious problem: I have a function with this signature:

void myFunction(double, double, double, double);

It is called continuously. While it is called continuously the memory of Browser.Subprocess.exe is rising all the time (could this be a memory leak?) and approximately after 800 calls, Browser.Subprocess.exe dies and crashes one minute later!

Did you try to call a function like above for 1000 times in a loop till yet? The result would be very helpful for me.

@amaitland
Copy link
Member Author

Possibly a memory leak. What scenario requires a method to be called over 800 times? It'll be awhile before I get time to look at this so feel free to investigate further on your own.

@amaitland
Copy link
Member Author

@tomtorell Thinking about your problem some more, and I'm not quite sure how to debug your issue, the fact that it's successful for at least a few hundred calls makes for a tricky debugging scenario. I had a quick check and the version of Cef we're using doesn't expose access to their logging api.

Are you able to modify one of the samples? If you can provide a close to real world example of your problem then that's a start. (Better than just calling a method in a loop, which is likely to cause a problem, though may not accurately reproduce your issue).

As an alternate solution, are you able to batch up your calls to reduce the number?

@perlun
Copy link
Member

perlun commented Sep 23, 2014

Cc #310, since that's the PR for the WIP branch.

@tomtorell
Copy link

@perlun actually I'm debugging a little bit this issue. It persists for me even in the CefSharp.WinForms.Example: If I do 800 Javascript calls to "bound.repeat("hi ", 5)" in the BindingTest.html the CefSharp.BrowserSubprocess.exe crashes.

@tomtorell
Copy link

@amaitland I'm using the Javascript Binding in an interactive Web-Application witch consumes user input. After some time, the user reaches the amount of 800 calls to my C# functions. Unfortunately it is quite difficult to provide a real world example. But I was able to reproduce the problem very easily:

I modified the BindingTest.html of CefSharp.WinForms.Example of the WIP branch to call "bound.repeat("hi ", 5)" 800 times in a loop. After 800 calls the CefSharp.BrowserSubprocess.exe crashes. This is exactly the count of calls, I can do in my application. See the modified BindingTest.html in the attachment.

I also debugged a little bit, but could not found the reason for the crash. (I'm absolutely new to this project.) I modified JavascriptMethodHandler.h of ...Subprocess.core a little bit, so I can count the number of calls coming in, setting a conditional breakpoint (ii = 799) to stop after 799 calls. The process crashes after the method Execute() returns.

By the way: I think, directly before the "return true;" of method Execute() a "delete response;" is missing?

The modified file JavascriptMethodHandler.h is attached also.

23-09-2014 13-54-46

23-09-2014 14-09-17

@amaitland
Copy link
Member Author

@tomtorell Thanks for the feedback, I'm sure there are at least a few places that need some additional cleanup code added.

@jornh jornh modified the milestones: 33.0.0-pre2, 33.0.0 Sep 26, 2014
@tomtorell
Copy link

@amaitland Could you reproduce the problem? Regards, Tom

@amaitland
Copy link
Member Author

@tomtorell I can successfully reproduce your issue, unfortunately as it just crashes I've got no idea as to what's causing it. We're currently in the processing of upgrading to a newer version of Cef at the moment so I don't have a whole lot of time to look into this further. Sorry.

Is there no way around this? Batch your calls together to reduce the number? Another option could be using a custom schema handler to implement XHR or WebsSockets?

XMLHttpRequest (XHR), WebSockets or similar can also be used for communication between processes. For example, an XHR request can be sent from JavaScript running in the render process to a resource handler implemented in the browser process via CefRequestHandler::GetResourceHandler or a custom scheme handler.

https://code.google.com/p/chromiumembedded/wiki/Architecture

@amaitland
Copy link
Member Author

@tomtorell It may also be worth opening a separate issue for this bug so that it doesn't get lost

@tomtorell
Copy link

@amaitland ok, I saw it crashing, when the method Execute() returns. Unfortunately I was not able to debug behind this point. I think it is the code of the cef library itself when you leave Execute(), and till yet I did not download the code of it. I think this problem should be caused by any resources (memory or handles ...), that are not freed. May be in two weeks, I can spend a little more time on this issue.

@amaitland
Copy link
Member Author

FYI -pre packages have been released to staging that include JS Binding
https://staging.nuget.org/packages/CefSharp.WinForms/33.1.0-pre01
https://staging.nuget.org/packages/CefSharp.Wpf/33.1.0-pre01

@jornh
Copy link
Contributor

jornh commented Oct 9, 2014

My tiny bit of first time user experience so far as posted to the Google Group 👯

@amaitland
Copy link
Member Author

The first -pre is out on nuget.org for all those looking for it

https://www.nuget.org/packages/CefSharp.WinForms/33.1.0-pre01
https://www.nuget.org/packages/CefSharp.Wpf/33.1.0-pre01

If you do find any bugs please provide detailed feedback including:

  • x64 or x86
  • Any relevant info in debug.log (generated by cef in your bin folder)
  • Steps to reproduce (code samples are even better)
  • StackTrace where relevant

@perlun
Copy link
Member

perlun commented Oct 10, 2014

Great work @amaitland! 👏 However, why 33.1.0-pre01, has there ever been a 33.0.0? 😄 Also, I think that pre1 makes more sense than pre01. I understand this is probably because of the NuGet limitation w/ SemVer versions (i.e. 33.1.0-pre.1 is not possible) but I find it quite unlikely that we will want to have more than 9 prereleases anyway... 😉

Just my 0.02€ of course. 😛

@amaitland
Copy link
Member Author

Hey @perlun,

As per #496 (comment) we decided to release a 33.0.0 stable without Js Binding (based on current master)

The tag is here https://github.com/cefsharp/CefSharp/releases/tag/v33.0.0

I understand this is probably because of the NuGet limitation w/ SemVer versions

Correct 😄 I'm hopeful we won't have more than 9 pre release versions, though I figured adding an extra 0 was so trivial that it would be worth the flexibility. The hope is to release more frequently with less changes. I guess we could have used the -beta tag, though I must admit up until 30 seconds ago I didn't know that existed, so live and learn I guess 😄

@jornh
Copy link
Contributor

jornh commented Oct 10, 2014

@perlun see https://github.com/cefsharp/CefSharp#nuget-packages for my meek attempt at a 10.000 foot picture.

Hope it suits your benevolent taste 😉

For a few moments I started regretting that I had added those http://shields.io badges - they suddenly turned up with missing images - but when it failed response with a fix https://twitter.com/Shields_io/status/520581905084088320 turned out to be quick.

@Bodekaer
Copy link
Contributor

Bodekaer commented Nov 4, 2014

Yep. I don't think it's an issue in cef/2171. I believe it's part of the jsb work.
Would it be best if I did it based on cef/2062-jsb then?

@amaitland
Copy link
Member Author

Would it be best if I did it based on cef/2062-jsb then?

Sure, that would be great, thanks!

@Bodekaer
Copy link
Contributor

Bodekaer commented Nov 4, 2014

There you go :) #566

@amaitland
Copy link
Member Author

There you go :) #566

Awesome, thanks! 👍

@amaitland
Copy link
Member Author

@tomtorell If you check out #589 it should hopefully resolve your issue.

@tomtorell
Copy link

@amaitland thank's a lot for that information! The last weeks I had a lot of work in an other project so actually I'm not up to date with the status of the java script binding. But this issue is still very importand to us, so I'll check out and test the #589. Was some of the CefSharp developers able to reproduce and correct the 800-call-problem?

@jornh
Copy link
Contributor

jornh commented Nov 11, 2014

@tomtorell latest status is that JS Binding as of today has been merged into master and that #590 is the new proposed fix for the 800-call-problem as you so aptly call it 😄 already updated to apply to master

Back story: The good news is that it looks like @sylvain-hamel and you are getting bitten by the same issue, that it looks like he found the root cause AND already has a proposed fix 👍 which he just updated to apply to master ...

@tomtorell
Copy link

@jornh great! I'll download, compile and test the fixed JS-Binding tomorrow. Afterwards I'll report here about the result.

@tomtorell
Copy link

Hi, I've downloaded the master branch form today, made the test I described in this thread above (09/23/2014) and it is stable now. I extended the test to the extreme number of half a million calls, witch consumes a CPU time of approximately three minutes, and even this heavy duty test is working fine! This amount of calls is pretty much more than I expect, any user will achieve in an interactive session. So, this issue is fixed. Thank you all for your help!

@jornh
Copy link
Contributor

jornh commented Nov 12, 2014

Preeetty nice confirmation to get for #590 😄 and that we did right in merging JS-Binding to master. Let's see how much other input we'll get on it ...

@jornh jornh modified the milestones: 37.0.0-pre01, 37.0.0 Nov 27, 2014
@vivekcoer
Copy link

Hey @amaitland ,
I needed JS closure support in my "asynchronous calls" -->> for that I tested it with Custom Scheme Handler and found it be working well. I have an example code at https://groups.google.com/forum/#!topic/cefsharp/zXSDXNxw6oY
My question is, is there a catch? Could I fully work with custom schemes like AJAX with full Closure support? I am refraining from using JS bindings for this whole purpose and wanted to make sure if I am on right track? Thanks.

@jankurianski
Copy link
Member

@vivekcoer For the past few months my app has been using AJAX calls with custom schemes to talk to C#. I also use AJAX long-polling requests where the response callback is fired a long time later in another thread. No problems at all.

@vivekcoer
Copy link

Thanks @jankurianski !
yeah, along with the JS closure right?
It means if I use Custom Scheme I dont face JS closure issues and there is no need to use "Asynchronous Bindings" & "Generic Message Router" (CEF https://code.google.com/p/chromiumembedded/wiki/GeneralUsage#Asynchronous_Bindings)!

What I am wondering is, if this was that easy, why did I everywhere see that asynchronous call backs along with JS closure are NOT possible using CEFSHARP? And that is why I am asking it here to make sure if I am doing everything right! What was the catch?

Finally, I have a base JS application which has tons of JS resources - do I need to have a custom scheme handler for all of them (combined or individually)? Or else may be I can directly use ///file protocol - if yes, how? Especially without any crossdomain/crossapp issues.

Thanks

@amaitland
Copy link
Member Author

My question is, is there a catch? Could I fully work with custom schemes like AJAX with full Closure support?

If you require Asynchronous calls then SchemaHandler is your best option. What makes you think there's going to be a problem with Closures? Your performing an AJAX call, same as any web browser, only difference is that instead of the request being transmitted over the network, it's handled locally.

I had a look at your code, I'd personally be using Tasks rather than Theads, other than that, it should be pretty straight forward.

What I am wondering is, if this was that easy, why did I everywhere see that asynchronous call backs along with JS closure are NOT possible using CEFSHARP?

What reference are you quoting?

Finally, I have a base JS application which has tons of JS resources - do I need to have a custom scheme handler for all of them (combined or individually)? Or else may be I can directly use ///file protocol - if yes, how? Especially without any crossdomain/crossapp issues.

Using file:/// is likely to give you crossdomain issues. I'd say you'd be best to load everything under the one Schema. If your JavaScript only changes when your application does, then I'd be inclined to embed the files as resources and let .Net take care of the loading part, if you come up with a consistent naming scheme for files/folders, you could easily use the ResourceManager for lookups.

e.g. https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/Properties/Resources.Designer.cs#L98

@vivekcoer
Copy link

Thanks a lot @amaitland ! Embedding the JS files as resources sounds good. One question, I should be able to debug the javascript in those files using chrome debugger tools - right? But for some reason in WPF example project I don't see the menu option to see the developer tools (however in WinForms example project I see that) - has that been omitted on purpose or is there a way to see dev tools in WPF example too? I am sorry but I am fairly new to Chromium/CEFSHARP.

Thanks

@amaitland
Copy link
Member Author

But for some reason in WPF example project I don't see the menu option to see the developer tools (however in WinForms example project I see that)

Nobody has got around to implementing it yet. Feature exists in both. All ChromiumWebBrowser controls inherit from IWebBrowser

https://github.com/cefsharp/CefSharp/blob/master/CefSharp/IWebBrowser.cs#L296

@vivekcoer
Copy link

Thanks @amaitland !

@vivekcoer
Copy link

Hello @amaitland @jankurianski @perlun
I am facing one issue. I am loading resource files from my local file system using file:/// (I disabled the security and allowed localfile loading in browser settings) and its working fine for me. Except that in one of JS files I am making a XMLHTTP POST request to another domain.
But this call apparently never reaches to server because in chrome debugger I keep getting the infamous "CAUTION: Provisional headers are shown" error in network tab - this error is only shown when the request never actually reaches the domain -
http://stackoverflow.com/questions/21177387/caution-provisional-headers-are-shown-in-chrome-debugger

Suspecting that it might be a cross domain issue I added CORS headers as below too (as below) but that didnt help either.

I added CORS headers - "Access-Control-Allow-Origin: https://***.com, Access-Control-Allow-Credentials: true"

Everything works fine in chrome browser with the same local files (with an added command line switch --disable-web-security).

please could you help me figuring out what is going wrong here?

chrome_issue

@amaitland
Copy link
Member Author

@vivekcoer As this is unrelated to Javascript Binding can you please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants