Re: [Cppcms-users] JSON-RPC dispatching together with Normal Web Page
Brought to you by:
artyom-beilis
From: Jon F. <jon...@jf...> - 2020-11-09 19:51:40
|
<html> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> </head> <body bgcolor="#FFFFFF" text="#000000"> <p>Glad to hear it. I've never actually used the C++CMS JSON RPC server class because the docs leave too much unsaid, making it far simpler to write my own handler. I think you might have to dig through the source to see what its actually doing. I put together a test environment made from the "clippings" you sent along and I'm not sure I made it as far as you did. :-) What I'm seeing is the call dying in the CORS authentication phase (OPTIONS req) my C++CMS app failing to respond with the appropriate "allowed" response, in fact it says nothing and FF just drops the request.</p> <p>"CORS" is fairly recent pseudo-security feature. Its possible that C++CMS is not prepared for it and a simple extension to the JSON RPC server class may be needed. But I could be getting ahead of myself.</p> <p>The primary thing you need to do is fire up your browser's "dev tools". The "console" section will allow you to call your javascript function, to manually trigger requests to the server side. It should also log the requests and responses made to your server. All XHR requests should come in two phases the "OPTIONS" request to ask the server for permission, followed by the actual JSON request you made, which would be a "POST" transaction. Check the request and response to make sure your getting what you expect. Often times what you see there will reveal the issue.</p> <p>I don't know your experience level so this page from MDN might be useful in understanding CORS: <a class="moz-txt-link-freetext" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS</a></p> <p>Anyhow I have client needs to attend to or I'd drill the rest of the way down. Use your browser's debugger and sprinkle "std::cerr << ..." stuff liberally in your server side code to get a picture of what its doing. On my setup I can call the RPC url with a generic client (browser, wget, curl, ...) and get "invalid content type" so I know the request is getting dispatched to the RPC handler. Yet an override of main() fails to show an URL hit the application so the call must be getting blocked further up in the class. maybe init()? Or I fat-fingered something? Like I said I'd have to drill down on the source to figure out what its up to.</p> <p>I'll try to help out as I can.</p> <p>- Jon<br> </p> <br> <div class="moz-cite-prefix">On 11/09/2020 09:29 AM, Varstray Pl wrote:<br> </div> <blockquote cite="mid:CAN2zg3Oqp=3pc...@ma..." type="cite"> <div dir="ltr"> <div>Ah! Ok. So this is actually very helpful!</div> <div><br> </div> <div>I've decided to go with mounting the rpc server in the webcomic's url space using the attach method you described above. The code for my webcomic page constructor is as follows:</div> <div>* * *<br> </div> <div><span style="font-family:monospace">webcomic::webcomic(cppcms::service &srv) : cppcms::application(srv){<br> attach(new json_service(srv), "rpc", "/rpc{1}", "/rpc(/(.*))?", 1);</span></div> <div><span style="font-family:monospace"> //.. various dispatcher and mapper calls.<br> </span></div> <div><span style="font-family:monospace">};</span></div> <div><span style="font-family:monospace">***<br> </span></div> <div><span style="font-family:monospace"><font face="arial,sans-serif">The browser now appears to be successfully calling the rpc server! Yay! Unfortunately (there's always an unfortunately, isn't there? xD), I think I haven't set up the handling of the rpc request properly within the server, because instead of a proper response, the widgets panel is simply filled with the text "Invalid JSON-RPC"</font>. <span style="font-family:arial,sans-serif">I'm not sure where in the pipeline things are going wrong, but here is how I've set up the rpc server. Maybe you can see what I'm doing wrong?</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">First, the basic class definition:</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *</span></span></div> <div><span style="font-family:monospace">class json_service: public cppcms::rpc::json_rpc_server{<br> public:<br> json_service(cppcms::service &srv);<br> <br> // Ajax Methods<br> void widgets();<br> };</span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">And then the implementation of the server constructor and the widgets method:</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *</span></span></div> <div><span style="font-family:monospace">json_service::json_service(cppcms::service &srv) : cppcms::rpc::json_rpc_server(srv)<br> {<br> bind("widgets", cppcms::rpc::json_method(&json_service::widgets, this),method_role);<br> }<br> <br> void json_service::widgets()<br> {<br> return_result("widgets via AJAX-RPC!!! Cool!");<br> }</span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">Finally, this is how the request is set up on the client side via javascript:</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><span style="font-family:monospace">function getWidgets() { <br> var xhr = new XMLHttpRequest(); <br> xhr.open("post", '/rpc');<br> <br> // Required by JSON-RPC over HTTP <br> xhr.setRequestHeader("Content-Type","application/json");<br> <br> // Configure JSON-RPC request.<br> var request = '{"method":"widgets"}';<br> <br> // Define our callback function.<br> xhr.onreadystatechange = function(){<br> if (xhr.readyState === 4){<br> var response;<br> <br> if (xhr.status === 200){<br> response = xhr.responseText;<br> } else {<br> response = 'Invalid Status: ' + xhr.status;<br> }<br> <br> document.getElementById('widgets').innerHTML = response;<br> }<br> }<br> <br> xhr.send(request);<br> return false;<br> } </span><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *<br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">The javascript method is pretty much taken from the json-rpc tutorial on the <a moz-do-not-send="true" href="http://cppcms.com">cppcms.com</a> website. Although because this method doesn't take any parameters(yet), I *think* perhaps the issue lies somewhere in the modifications I made for sending a request for a non-parameter method, whereas the tutorial method does take parameters. Also, up till this point, diagnostic information on stderr and stdout has been very helpful, but now there doesn't appear to be any stderr output at all, lol.</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">I *can* verify that on the browser end the rpc call is actually being sent to the rpc server, and because 'Invalid RPC-JSON' is different from 'Invalid Status: bla bla', I think that the getWidgets() method is actually getting a proper response from the rpc server. It's just clearly there's something else going wrong somewhere.</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">* * *</span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif">Thank you for your help, Jon, and sorry for any additional trouble. I'll also keep searching on my end for an answer as well. ^^;<br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"><br> </span></span></div> <div><span style="font-family:monospace"><span style="font-family:arial,sans-serif"></span><br> </span></div> </div> <br> <fieldset class="mimeAttachmentHeader"></fieldset> <br> <br> <fieldset class="mimeAttachmentHeader"></fieldset> <br> <pre wrap="">_______________________________________________ Cppcms-users mailing list <a class="moz-txt-link-abbreviated" href="mailto:Cpp...@li...">Cpp...@li...</a> <a class="moz-txt-link-freetext" href="https://lists.sourceforge.net/lists/listinfo/cppcms-users">https://lists.sourceforge.net/lists/listinfo/cppcms-users</a> </pre> </blockquote> <br> <pre class="moz-signature" cols="75">-- Sent from my Devuan Linux workstation -- <a class="moz-txt-link-freetext" href="https://devuan.org/">https://devuan.org/</a> "Init Freedom", Yeah! Jon Foster JF Possibilities, Inc. <a class="moz-txt-link-abbreviated" href="mailto:jo...@jf...">jo...@jf...</a> </pre> </body> </html> |