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:CAN...@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>
|