Apache Thrift Javascript client to C++ Server [duplicate] - 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

protobuf.js using CommonJS?

I am relatively new to JS but very familiar with protobuf. I'm currently designing a web page hosted from a Java HTTP server, and would like to implement protobuf communication between them.
My issue is on the browser side. After some research I found the protobuf.js git page and attempted to use this within my javascript. I ran into issues firstly getting the module over HTTP because
<script src="//cdn.rawgit.com/dcodeIO/protobuf.js/6.X.X/dist/protobuf.js"></script>
uses text/plaintext and fails to return. Adding a type=text/javascript just led to protobuf is not defined.
I then tried to take the project source into my web root, and directly use this:
<script type="text/javascript" src="./js/protobuf-js/src/index.js" ></script>
and:
import * as protobuf from "./js/protobuf-js/src/index.js";
This worked and the web server returned the file. Now, this is where my understanding reaches it's limits. From what I can tell from the README page on git, it distinctly says
"The library supports CommonJS and AMD loaders and also exports globally as protobuf."
If I look inside index.js I see the following:
var protobuf = module.exports = require("./index-light");
which throws a Module is not defined in ES module scope exception in browser.
Nowhere else online could I find working examples of the protobuf.js being used in commonJS as it states in the git, it all refers to Node.js which I don't want to use as i'm using Java for the webserver side of things.
Am i being really dumb and missing something obvious?
Thanks
There are example in https://github.com/protobufjs/protobuf.js.
a small example:
hello.proto
syntax = "proto3";
message Test{
string msg=1;
}
test.html
<html lang="en">
<head>
<script src="//cdn.rawgit.com/dcodeIO/protobuf.js/6.11.3/dist/protobuf.js"></script>
</head>
<body>
<script>
function test(){
protobuf.load("hello.proto", function(err, root) {
var TestMsg = root.lookup('Test');
var payload = {msg:'hello'};
var result = TestMsg.verify(payload);
if(result) throw Error(result);
var msg = TestMsg.create(payload);
var binMsg = TestMsg.encode(msg).finish(); // this is the binary protobuf message
// to handle blob data from server via websocket, you need handle like below
// event.data.arrayBuffer().then(buf =>{
// var msg = TestMsg.decode(new Uint8Array(buf));
// }
// deserialize
var msg2 = TestMsg.decode((binMsg));
console.log(msg2.toJSON());
alert(msg2.msg);
});
}
</script>
<input type="button" value="test" onclick="test()">
</body>
</html>

How to change endpoints for different stages in javascript [client side]?

I think it might have asked before. But I couldn't find any results based on my search keywords.
In my use case I am configuring endpoints based on stage information [desktop, preprod, prod]. I am using golang for backend. In the backend I use the APP_STAGE environment variable to read the respective configs. For example,
fileName = APP_STAGE + "-endpoints.cfg"
And I export the variable before starting the server.
$export APP_STAGE="desktop"
And desktop-endpoints.cfg will look like this,
{
"featured" : {
"httpendpoint": {
"url": "http://localhost:8081/api/services/featured/"
}
},
"latest" : {
"httpendpoint": {
"url": "http://localhost:8081/api/services/latest/"
}
}
}
But how can I achieve this in client side [javascript]? I have files in the following structure,
app/
view.js
featured.js
home.js
Each of the file uses different endpoints to make ajax calls. How can read the stage config based on some variable [if not env variable] in javascript?
Could someone help me with this? I am fairly new to javascript.
Thanks.
JavaScript files are executed at client side, by the browser. The browser does not have access to the server config files, so it is the server's responsibility to read/get proper config values and make them available to the client.
There are multiple ways to deal with this. I will outline some possible solutions.
1. Include the correct endpoints in the HTML files
You may choose to include the correct endpoints in the HTML files that refer to the javascript files in which they would be used.
The HTML files would be templates and not static files, and you can use the html/template package to execute those templates to include the necessary URLs and everything else you need, and generate the final HTML that will be sent to the clients.
The HTML template may contain a <script> tag initializing certain JavaScript variables, which then can be used from the included JavaScript files.
Here's a simple example passing the featured httpendpoint.
HTML Template ("home.html"):
<html>
<head>
<script>
var featuredHttpEndpoint = "{{.FeaturedHttpEndpoint}}";
</script>
<script src="view.js"></script>
<script src="featured.js"></script>
<script src="home.js"></script>
</head>
<body>Your body</body>
</html>
And the handler that would serve this HTML template:
var homeTempl = template.Must(template.New("").ParseFiles("home.html"))
func homeHandler(w http.ResponseWriter, r *http.Request) {
m := map[string]interface{}{
// Insert the value of endpoint from your config
"FeaturedHttpEndpoint": "http://localhost:8081/api/services/featured/",
}
if err := homeTempl.Execute(w, m); err != nil {
// Handle error
}
}
Mapping the home handler e.g.:
http.HandleFunc("/index.html", homeHandler)
And make sure the home page is not cached, so the browser will always ask for a fresh copy in which your server can insert the actual config values.
2. Perform AJAX requests from the JavaScript files
You may choose to perform AJAX requests from the JavaScript files to query the necessary information. A simple example of this can be found in this question: Dynamically refresh a part of the template when a variable is updated golang
In a real-life example you would transmit all the config values that the client needs with one request (e.g. in JSON format), here I only transmit a single value.
Getting / sending only the featured httpendpoint:
In JavaScript:
var featuredHttpEndpoint = "";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var config = JSON.parse(xhr.responseText);
featuredHttpEndpoint = config.FeaturedHttpEndpoint;
}
}
xhr.open("GET", "/config.json", true);
try {
xhr.send();
} catch (err) {
// handle error
}
And the Go handler providing the config values:
func configHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
m := map[string]interface{}{
// Insert the value of endpoint from your config
"FeaturedHttpEndpoint": "http://localhost:8081/api/services/featured/",
}
if err := json.NewEncoder(w).Encode(m); err != nil {
// Handle error
}
}
Which must be mapped to the path the client calls, e.g.:
http.HandleFunc("/config.json", configHandler)
3. Use Javascript files as templates
You may also choose to make your Javascript files templates, and when serving them, you may use a template engine to include endpoints based on your environment / APP_STAGE. See point #1 as an example to serving templates.
If you're going down this path, you have to take care of properly configuring caching of the Javascript files, as the browser will not ask you again for the js files if their caching info says they are not expired.

Dynamically get web socket URL

I have a Play 2.5 application that uses a web socket. In my Controller I establish it as
def socket = WebSocket.accept[JsValue, JsValue] { request =>
ActorFlow.actorRef(out => TroiWebSocket.props(db, out, comm.communicator, system))
}
And, it's accessed in my routes as
GET /push-notifications controllers.Application.socket
As, currently, my application is running locally, I can reference the socket in a javascript file using
var socket = new WebSocket("ws://localhost:9000/push-notifications");
However, I'm starting to move my stuff away from the localhost, and need a way to reference the url in my javascript file. This URL might change (and could be different depending on the development environment). So, how can I reference this URL dynamically? That is, how do I say
var socket = new Websocket(URL_OF_WEBSOCKET)
I thought of breaking it up in my config files and trying to do it that way, but I'm not so sure that would work.
Any and all help would be appreciated.
If you are using plain javascript. Declare a File config.js and define some global Object with some config data.
<html>
<head>
<script>
var config = {
"localWSUrl" : "ws://localhost:9000/socket",
"wsUrl" : "ws://serverurl.com:443/socket"
}
</script>
<script>
console.log(config.wsUrl);
</script>
</head>
<body>
</body>
</html>
For simplicity sake I wrote everything in one file. You would exclude the config part and import the file via the script tag's src attribute. And then you can reuse it where you need it.
If the URL to get main page of your application is the same or partially same to connect websocket, suppose:
Url app: myapp.com
Websocket url: myapp.com/push-notification
So you could do in your js file using window.location of js standard api
var tcp = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
var host = window.location.host;
var path = '/push-notification';
var ws = new WebSocket(tcp+host+path);
Something like that..
I hope It helps.

How to pass a value from WinForm (C#) to an altogether separate Javascript client chat application

I have a chat application in which I have a client side(javascript) and server-side which is WinForms. I want to pass a value from my FrmConsole.cs file to my converse.js file. Is there any way I can achieve this? I am using XMPP protocol for connecting the client and operator console and I have my own ejabberd server running for the same.
For Example I want to pass this string from my C# code to my Javascript file:
private string GetStringValue()
{
return "A string value";
}
And this would be my javascript side code:
<script language="javascript" type="text/javascript">
var stringValue = '<%=GetStringValue();%>';
alert(stringValue);
</script>
I tried this but its not throwing the expected alert. In the alert it shows
<%=GetStringValue();%>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
function showstring(){
var stringValue = '<%=GetStringValue();%>';
alert(stringValue);
</script>
main body:
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Javascript", "javascript:showstring();", true);

Pusher client subscribed and running from command line

I have integrated some script on my php file.
It is reading the Pusher channel and does several actions when there is a new event on the listed channel.
If I run on the browser:
http:/localhost/pusher.php
and let it open the pusher connection keeps reading, however if I close it OR run on the command line:
php pusher.php
the script opens and ends in less than one second closing the connection and not reading future entries.
Question: What is the simpler way to run the (pusher) js and keep it opened and reading under the command line?
<?php require 'vendor/autoload.php'; ?>
<html>
<script src="//js.pusher.com/2.2/pusher.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" language="javascript"> var pusher = new Pusher('key'); var channel = pusher.subscribe('betfair');
channel.bind('bets', function(data) {
var a = data.market_id;
var b = data.selection;
var c = data.stake;
var d = data.odd;
var e = data.bet_type;
record(a, b, c, d, e);
});
function record(a,b,c,d,e) { console.log(a);
jQuery.ajax({
type: "POST",
url: 'time2.php',
data: {a, b , c , d, e},
success:function(record) {
console.log(data);
}
});
}
</script> </html>
JavaScript is almost strictly a client side language (exceptions being things like Rhino, nodeJS, etc), the things you are trying depend on the environment provided by the web browser, or more specifically a virtual machine attached to the browser that interprets the JS. You may have heard of V8 for example which is used by Chrome.
When you run the script via the command line it simply renders that JS. Nothing is actually parsing it.
You need to look at a PHP HTTP client like cURL (or maybe look at Guzzle these days).
As for a long ruinning server side process... These tasks are typically run by what people call a daemon. Maybe read this to get started on that topic: Run php script as daemon process Knowing what to Google for you should find plenty on the topic.

Categories

Resources