javascript Thrift client hangs - javascript

I have the following Thrift client code in javascript:
<script language="javascript" type="text/javascript" src="thrift.js" />
<script language="javascript" type="text/javascript" src="QuantSvc_types.js" />
<script language="javascript" type="text/javascript" src="QuantSvc.js" />
<script language="javascript" type="text/javascript">
function calc() {
var transport = new Thrift.Transport("http://localhost:9997/QuantSvc/");
var protocol = new Thrift.Protocol(transport);
var client = new QuantSvcClient(protocol);
try {
result = client.ListAllVariables()
} catch(ouch) {
alert("An exception occurred!")
}
}
</script>
Which is triggered when I push a button on my HTML page. Then, I have the following server-side Scala code, running on localhost:9997:
object Application extends App {
val handler = new QuantSvcHandler()
val processor = new QuantSvc.Processor(handler)
val serverTransport = new TServerSocket(9997)
val server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor))
}
Where the QuantSvcHandler's ListAllVariables function is (basically a skeleton function, just trying to get things to work):
override def ListAllVariables(): util.List[Attributes] =
{
var input = scala.collection.mutable.Buffer[Attributes]()
input
}
I put a breakpoint at the first line of ListAllVariables, and also a few places in the QuantSvcHandler processor. I run the server in debug in intellij IDEA, open my HTML page in Chrome, and push the button (the one that calls the javascript calc() function). The button stays stuck and I see no kind of response on the server, the breakpoints aren't being hit.
Any ideas about what I'm doing wrong?

You mix a HTTP client with a socket server.
Although HTTP uses sockets, the Thrift HTTP transport is not compatible with the Thrift Sockets transport. You need to set up the exact same protocol/transport stack on both ends. The only exception to that rule is that some server transports implicitly require an additional framed transport layer on the client side.
So the solution is to use a HTTP server. Depending on the version you use, you may also have to switch to the JSON protocol.

Related

Use WebSocket wrapper for all iframe, ws requests

I'm trying to experiment if I can force all elements within an iframe (of dask-labextension to be precise) to use a custom web socket wrapper following answers to this question with the following snippet:
const iframe = document.getElementsByTagName("iframe")[0];
const originalSocket = iframe.contentWindow.WebSocket;
iframe.contentWindow.WebSocket = function(...args) {
const socket = originalSocket(...args);
console.log("Creating new socket: ", socket);
return socket;
};
iframe.contentWindow.WebSocket.prototype = originalSocket.prototype;
iframe.contentWindow.WebSocket.prototype.constructor = iframe.contentWindow.WebSocket;
JupyterLab's Dask Extension loads a bunch of dashboards as iframes, each of which includes the following bokeh js files:
<head>
<meta charset="utf-8">
<title>Bokeh Application</title>
<script type="text/javascript" src="static/js/bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314"></script>
<script type="text/javascript" src="static/js/bokeh-gl.min.js?v=e5df31fd9010eacff0aa72d315264604b5e34972ba445acea6fce98080eecf33acf2d2986126360faaa5852813cffa16f6f6f4889923318300f062497c02da4e"></script>
<script type="text/javascript" src="static/js/bokeh-widgets.min.js?v=8a1ff6f5aa0d967f4998d275803bbb111d928fd9f605ef9e1f30cfd021df0e77224ee3d13f83edb3a942f6e4ccc569ee5dd8951a8aa6cb600602463b90c65a87"></script>
<script type="text/javascript" src="static/js/bokeh-tables.min.js?v=ae2903e57cf57f52819fdf4d938c648982b51c34f73b6e653a0f3bb3c8ab44f338505931ace43eafc1636e215492e2314acf54c54baffb47813b86b4923a7fe0"></script>
<script type="text/javascript" src="static/js/bokeh-mathjax.min.js?v=176c36fdbcd8fc1019fc828101a2804081a35baf4018d7f2633cd263156b593aa73112f400112b662daa0590138b74851bc91f1f2a5fbf5416ee8c876c3e0d0c"></script>
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
</head>
But it looks like all of Bokeh's websocket requests goes through a separate WebSocket object, instead of my custom wrapper. The following are console logs coming from Bokeh:
[bokeh] setting log level to: 'info'
bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:587 [bokeh] Websocket connection 0 is now open
bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:165 [bokeh] document idle at 94 ms
bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163 Bokeh items were rendered successfully
The console output seems to be missing the console log I have around my custom wrapper, which makes me think it uses a different WebSocket function.
Is there a way to force Bokeh (or any other included script's) websockets to use my custom wrapper?

I am running a basic HTML & Javascript app (connecting to Google and Twilio API), and keep getting the reference error that a variable is not defined

I built a basic HTML & Javascript app to translate a few words from the Google Translate API then text them to a number via Twilio. Here is my HTML:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src="script.js"></script>
</head>
<body>
<p>Click the button to receive 3 Hebrew texts</p>
<input id="clickMe" type="button" value="clickme" onclick="myFunction();" />
</body>
</html>
And here is script.js:
function myFunction(){
// Imports the Google Cloud client library
const {Translate} =require('#google-cloud/translate').v2;
// Creates a client in Google API
const projectId = 'Xx'
const keyFilename = '/Users/x/Downloads/vocal-lead-306923-b3d8f6749397.json'
const translate = new Translate({projectId, keyFilename});
const lang = "he"
// Creates a client in Twilio API
const accountSid = 'Xx'
const authToken = 'Xx'
const client = require('twilio')(accountSid,authToken);
/** Set variables for input in Google API */
const text = ['One day'];
const target = lang;
async function translateText() {
// Translates the text into the target language. "text" can be a string for
// translating a single piece of text, or an array of strings for translating
// multiple texts.
let [translations] = await translate.translate(text, target);
translations = Array.isArray(translations) ? translations : [translations];
//console.log('Translations:');
translations.forEach((translation, i) => {
setTimeout(() => {
// Sends messages via Twilio
client.messages.create({
to:'+phone',
from:'+phone',
body: `${translation}`
})
}, i * 10000);
});
}
translateText();
}
myFunction();
By itself, the script works but it doesn't work when I run it from my local browser. I hit inspect and I get this error:
Uncaught ReferenceError: require is not defined
at myFunction (script.js:5)
at HTMLInputElement.onclick (index.html:8)
I took out auth keys/any personal data but I think that is all correct. Any advice would be helpful!
If you're trying to run the script in browser, it won't work. This is because require() is a nodejs feature, and so anything that depends on libraries by require needs to be done in a nodejs backend (you can communicate between html frontend and nodejs backend over http for example; see https://expressjs.com/ and https://nodejs.org/en/ the latter has builtin http but for routing express is recommended).
You mention that you've removed private information for this SO post, but keep in mind that when you publish this site and the script.js is visible to the user (i.e. inspect element) it'll be freely accessible. It is not good practice to put secrets in the frontend code. Consider this: a bad actor uses your API key to send spam SMS on your behalf... not good.
Also see: How to use google translation api with react

calling on a javascript push service via c++

I have a Qt application that needs to call on a javascript push service. Basically there is no \endf in the http. (a currency ticker)
<script src="//js.pusher.com/2.2/pusher.min.js" type="text/javascript"></script>
<script type="text/javascript">
var pusher = new Pusher("cb65d0a7a72cd94adf1f");
var channel = pusher.subscribe("ticker.160");
channel.bind("message", function(data) {
//console.log(data);
var topbuy = data.trade.topbuy;
console.log("Price: ", topbuy.price,
"Quantity:", topbuy.quantity);
});
</script>
How do I execute this existing code in C++? (make it a C++ ticker and not just a JavaScript ticker)
According to http://pusher.com/docs/pusher_protocol, they use WebSockets for communication.
So you probably want to look at some library like http://www.zaphoyd.com/websocketpp or the Casablanca SDK from Microsoft https://casablanca.codeplex.com/
With one of these it should be fairly easy to connect and receive the Pusher messages.

XMLRPC client in Javascript

I am trying to make XMLRPC connection between Server (C code) and Client (In Javascript). Client sends two numbers and server adds them and returns back.
Server(in C code) is supposed to get data in the following XML form:
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>sample.add</methodName>
<params>
<param><value><i4>a</i4></value></param> // a and b are numbers to be added
<param><value><i4>b</i4></value></param> // a and b are numbers to be added
</params>
</methodCall>
I used mimic library for JS. So here is the client side script:
<title>Mimic - JavaScript XML-RPC Client</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<script src="mimic/mimic.js"language="javascript"></script>
....
<center>
<input type="text" id="n1"/>
<input type="text" id="n2"/>
<input type="button" onclick="Add_Request();" value="Request"/>
...
<script language="javascript">
function Add_Request() {
var method = "sample.add";
var request = new XmlRpcRequest("demos/calc.php", method);
request.addParam(document.getElementById("n1"));
request.addParam(document.getElementById("n2"));
var response = request.send();
alert(response.parseXML());
}
</script>
But client does not work.
Where did I make mistake or...?
In which form does Javascript send XML data to the server?
any advice would be appreciated
Thanks in advance!!!
P.S. Implementation of XMLRPC Client and Server in C code work fine.
You are not passing the correct url to the XmlRpcRequest function. You need to reference the mimic-sourceforge address. (This is assuming you are not running your own XML-RPC Server and just trying out this code)
...
<script language="javascript">
function Add_Request() {
var method = "sample.add";
var request = new XmlRpcRequest("http://mimic-xmlrpc.sourceforge.net/demos/calc.php", method);
request.addParam(document.getElementById("n1"));
request.addParam(document.getElementById("n2"));
var response = request.send();
alert(response.parseXML());
}
</script>
...
If you are running this on chrome from localhost, you will eventually get a CORS issue.
Follow this thread for help with that:
Response to preflight request doesn't pass access control check

How can I run a local Windows Application and have the output be piped into the Browser

I have Windows Application (.EXE file is written in C and built with MS-Visual Studio), that outputs ASCII text to stdout. I’m looking to enhance the ASCII text to include limited HTML with a few links. I’d like to invoke this application (.EXE File) and take the output of that application and pipe it into a Browser. This is not a one time thing, each new web page would be another run of the Local Application!
The HTML/java-script application below has worked for me to execute the application, but the output has gone into a DOS Box windows and not to pipe it into the Browser. I’d like to update this HTML Application to enable the Browser to capture that text (that is enhanced with HTML) and display it with the browser.
<body>
<script>
function go() {
w = new ActiveXObject("WScript.Shell");
w.run('C:/DL/Browser/mk_html.exe');
return true;
}
</script>
<form>
Run My Application (Window with explorer only)
<input type="button" value="Go"
onClick="return go()">
</FORM>
</body>
Have the executable listen on a port following the HTTP protocol.
Then have the web page make AJAX-style HTTP requests to the local port with JAvascript.
The executable returns text.
The web page updates itself through DOM manipulation in Javascript.
Yes, this works. It is happening 5 feet away from me right now in another cubicle.
This is called CGI
Your already using WScript to launch, it can also read StdOut.
<html>
<head>
<script type="text/javascript">
function foo() {
var WshShell = new ActiveXObject("WScript.Shell");
var oExec = WshShell.Exec("ipconfig.exe");
var input = "";
while (!oExec.StdOut.AtEndOfStream) {
input += oExec.StdOut.ReadLine() + "<br />";
}
if (input)
document.getElementById("plop").innerHTML = input;
}
</script>
</head>
<body onload="foo();">
<code id="plop"></code>
</body>
</html>
It would be easier to have your EXE create a temp file containing the HTML, then just tell Windows to open the temp HTML file in the browser.

Categories