NodeJS: thrift vs thrift-http package - which one to use? - node.js

What is the difference between these two packages to use thrift on NodeJS:
- thrift
- thrift-http
At first glance it appears thrift-http would be needed to use thrift over http but I installed the thrift package and it does have a createHttpConnection method defined in it. Here is sample code I wrote:
var thrift = require('thrift');
var myService = require('./gen-nodejs/MyService');
var transport = thrift.TBufferedTransport;
var protocol = thrift.TBinaryProtocol;
// connect to proxy on 127.0.0.1:8888
var connection = thrift.createHttpConnection('127.0.0.1', 8888, {
transport : transport,
protocol : protocol,
path: 'http://localhost:5331/myhandler',
});
connection.on('error', function(err) {
console.log(err);
});
// Create a client with the connection
var client = thrift.createHttpClient(myService, connection);
console.log('calling getTotalJobCount...');
client.getTotalJobCount(function(count)
{
console.log('total job count = ' + count);
});
But when I run it I get this:
total job count = NULL
This is not as expected as the service returns an integer which cannot appear as NULL in the client callback. I can't find the link now, but yesterday I read somewhere that thrift only supports TJSONProtocol over http. Is that correct even now? And is that the reason why I am seeing a NULL? Also where can I see the source code for thrift in nodejs? This is the first link that appears in Google when searching for "thrift nodejs" and it seems the code is completely outdated.

The thrift package is the one provided by the Apache Thrift project team.
The other one is someone elses package, not related to the "official" sources in any way. After a quick check against the relevant commits, the version of the files seems to be 0.9.3 as well, which is the most recent official release. However, I can't say whether all these files are entirely original, or if they have been modified. You will have to verify that on your own (or just trust that guy).

Related

How to connect to RouterOS via Nodejs WebSocket?

I'm learning websocket nodejs, I want to connect to routeros via websocket like the https://github.com/aluisiora/node-routeros/ package, the package is too broad, I just want to know how to connect.
I've read the official documentation https://wiki.mikrotik.com/wiki/Manual:API, but I'm having trouble understanding it.
I have tried it this way, but did not get any response:
client.connect(port, host, function () {
console.log("Connected");
client.write(encodeString("/login"));
client.write(encodeString(`=name=${user}`));
client.write(encodeString(`=password=${password}`));
});
client.on("data", function (data) {
console.log("Received: " + data); // not excetue
});
I'm looking for code samples to connect to routeros via nodejs socket, hopefully someone shares here.
Thanks in advance, I really appreciate any answer.
Take into consideration the next things:
RouterOS API has it's own protocol, it has a bit of complexity. The official wiki tell us how to interact with it at LOW LEVEL. For these reason it's very difficult to understand. Isn't for a High Level programmer. Don't worry, We have all been through here.
Routeros v7 have a REST API, that will make the job easier, the exchange language is HTTP protocol, easy right? Actually is at beta stage.
RouterOS Wiki have other package for node.js that seems more easy: Mikronode
solution
Install mikronode package
$ npm install mikronode
use it:
var api = require('mikronode');
var connection = new api('192.168.0.1','admin','password');
connection.connect(function(conn) {
var chan=conn.openChannel();
chan.write('/ip/address/print',function() {
chan.on('done',function(data) {
var parsed = api.parseItems(data);
parsed.forEach(function(item) {
console.log('Interface/IP: '+item.interface+"/"+item.address);
});
chan.close();
conn.close();
});
});
});

Why would setting readPreference nearest generate not master errors?

We are using a node stack to connect to a mongo replica set. Because our replicas are geographically distributed, we would like to use the readPreference option in the URI and set it to nearest. But when we do so, while performance is greatly improved, we start getting "not master" errors.
Am I misunderstanding the use of the flag?
We are using mongo 2.6.3 and we are using version 2.0.24 of the mongodb node library.
The URI for the connection is:
mongodb://mongo-1:27017,mongo-2:27017,mongo-3:27017,mongo-4:27017,mongo-5:27017/db?replicaSet=main&readPreference=nearest
Burc
Option 1:
You could append slaveOk to end of connection URI. readPreference tells mongodb that how you'd like to read data and slaveOk instructs that it's OK to read from secondaries (bit duplicate) but works.
e.g.
mongodb://mongo-1:27017,mongo-2:27017,mongo-3:27017,mongo-4:27017,mongo-5:27017/db?replicaSet=main&readPreference=nearest&slaveOk=true
please see &slaveOk=true and end of URI.
https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html#read-preference
Option 2:
if above solution is not working, you'll need to modify code:
var client = require('mongodb').MongoClient;
var uri= "mongodb://mongo-1:27017,mongo-2:27017,mongo-3:27017,mongo-4:27017,mongo-5:27017/db?replicaSet=main";
Please note that I have modified connection uri. Instead of setting readPrefference in Uri, I moved it to as db option in MongoClient.connect.
var options = {db:{readPreference:"ReadPreference.NEAREST"}};
client.connect(uri, options, function(err, db){
if(err){
console.log(err);
return;
}
db = db.collection('data');
db.findOne({}, function(err, result){
console.log(result);
});
});
I have tested in nodejs driver 2.2 and hopping it should work in 2.0 version too.
It seems like there was a bug in the driver which was fixed in 2.0.28, where findAndModify used the readPreference setting. Upgrading the driver to the latest release seemed to have fixed the problem.
2.0.x drivers history

Transport Settings in Socket.IO 1.4.x

I have been tinkering with deployd on Heroku using this gist as a starting point:
https://gist.github.com/facultymatt/5373247
Line 20 of that server.js tries to set transports for socket.io like so:
server.sockets.manager.settings.transports = ["xhr-polling"];
But encounters this error:
Cannot read property 'settings' of undefined.
From research so far it seems this approach is deprecated in socket.io 1.4.5. However, if that's so I am not clear on how I should address this setting.
My question is similar to this one. But differs in that I seek to change the settings once socket.io is already constructed by and attached to an instance of deployd.
Set it on creation:
var server = deployd({
socketIo: {
options: { transports : ['xhr-polling'] }
}
});
Or if you can't do that, change it runtime (this is a hack):
server.sockets.server.eio.transports = ['xhr-polling'];
(This is still supported for backwards compatibility:)
server.sockets.server.set('transports', ['xhr-polling']);

Connecting to socket.io 1.x manually using websockets, capacity testing

I am working with a nodejs express server which uses socket.io to communicate an iOS client, and am having a little trouble trying to test how many clients can connect and exchange data at any one time.
My goal is to be able to run a script which connects to socket.io with thousands of different sessions, as well as send and receive data to understand our system's scale. Currently we are using a single dyno on Heroku but will likely be considering other options on AWS soon.
I have found code which should do what I am trying to do for earlier versions of socket.io, such as this, but have had issues since it seems v1.x has a very different handshake protocol. I tried out using the socket.io-client package, but trying to connect multiple times only simulates use of one session, I need to simulate many in independent users.
I have been picking apart the socket.io-client code, but have only gotten so far as creating a connection - I am stuck on the sending data part. If anyone has any knowledge or could point to some written resources on how data is sent between a client and a socket.io server, it would help me out a lot.
Here's what I have so far:
var needle = require('needle'),
WebSocket = require('ws'),
BASE_URL = 'url-to-socket-host:5002';
var connectionNo = 0;
needle.get('http://' + BASE_URL + '/socket.io/?EIO=3&transport=polling&t=1416506501335-0', function (err, resp) {
// parse the sid
var resp = JSON.parse(resp.body.toString().substring(5, resp.body.toString().length));
// use the sid to connect using websockets
var url = 'ws://' + BASE_URL + '/socket.io/?EIO=3&transport=websocket&sid=' + resp.sid;
console.log(connectionNo + ' with sid: ' + resp.sid);
var socket = new WebSocket(url, void(0), {
agent: false
});
socket.on('open', function () {
console.log('Websocket connected: ' + connectionNo);
// I don't understand how to send data to the server here,
// from looking at the source code it should use some kind
// of binary encoding, any ideas?
socket.on('message', function (msg) {
console.log(msg);
});
});
});
I will continue deconstructing the socket.io-client code but if anyone has any clues or recourses that may help, let me know. Thanks.
I ended up setting for using the socket.io-client npm package which has the ability to connect to a new session on every connection. I found an example benchmark in this issue.
There is not so much need for me to manually connect to socket.io using pure websockets and HTTP, but thanks to Yannik for pointing out the parser in use. The spec of the inner workings of v1.x can be found here.
Thanks!
The problem my reside in the fact that you are not using socket.io in your client code. You have imported ('ws') which is another module whose docs are here: https://www.npmjs.org/package/ws.
You probably want to ws.send('something');. When you receive a message in ws, it also comes with an object with a property indicating whether it is binary data or not. If it is, you will need to concatenate the chunks incrementally. There is a canonical way to do this which you can find via google. But it looks a little like this:
var message;
socketConnection.on('data', function(chunk){ message += chunk});

Is there a browserless websocket client for Node.js that does not need to use a browser?

Socket.IO, etc all require the using of browser on the client side....just wondering, how can we have browserless websocket client for node.js ?
Current Recommendation
Use WebSocket-Node with my wrapper code (see below). As of this writing, no other public project that i know of supports the new hybi specification, so if you want to emulate current browser releases, you'll need WebSocket-Node. If you want to emulate older browsers, such as mobile Safari on iOS 4.2, you'll also need one of the other libraries listed below, but you'll have to manage "WebSocket" object name collisions yourself.
A list of public WebSocket client implementations for node.js follows.
Socket.IO
The socket.io client-test WebSocket implementation does hixie draft 75/76, but as of this writing, not hybi 7+.
https://github.com/LearnBoost/socket.io/blob/master/support/node-websocket-client/lib/websocket.js
i'm asking if they intend to update to hybi 7+:
http://groups.google.com/group/socket_io/browse_thread/thread/d27320502109d0be
Node-Websocket-Client
Peter Griess's "node-websocket-client" does hixie draft 75/76, but as of this writing, not hybi 7+.
https://github.com/pgriess/node-websocket-client/blob/master/lib/websocket.js
WebSocket-Node
Brian McKelvey's WebSocket-Node has a client implementation for hybi 7-17 (protocol version 7-13), but the implementation does not provide a browser-style WebSocket object.
https://github.com/Worlize/WebSocket-Node
Here is the wrapper code I use to emulate the browser-style WebSocket object:
/**
* Wrapper for Worlize WebSocketNode to emulate the browser WebSocket object.
*/
var WebSocketClient = require('./WorlizeWebSocketNode/lib/websocket').client;
exports.WebSocket = function (uri) {
var self = this;
this.connection = null;
this.socket = new WebSocketClient();
this.socket.on('connect', function (connection) {
self.connection = connection;
connection.on('error', function (error) {
self.onerror();
});
connection.on('close', function () {
self.onclose();
});
connection.on('message', function (message) {
if (message.type === 'utf8') {
self.onmessage({data:message.utf8Data});
}
});
self.onopen();
});
this.socket.connect(uri);
}
exports.WebSocket.prototype.send = function (data) {
this.connection.sendUTF(data);
}
SockJS
Just for reference, Marek Majkowski's SockJS does not include a node client. SockJS's client library is simply a browser dom wrapper.
https://github.com/sockjs/sockjs-client
Having just gone through this, I have to recommend:
https://github.com/Worlize/WebSocket-Node
Due to it's excellent documentation.
https://github.com/einaros/ws comes a close second.
Both are active and being kept up to date at this time.
Remy Sharp (#rem) wrote a Socket.io-client implementation that works on the server. I think this is what you're looking for: https://github.com/remy/Socket.io-node-client
A Node.js server is in no way bound to a web browser as a client. Any program can use whatever socket library is provided by its supporting libraries to make a call to a Node.js server.
EDIT
Responding to your comment: don't forget that Node.js is Javascript! If you want to execute code periodically -- in much the same way that a daemon process might -- you can use setInterval to run a callback every n milliseconds. You should be able to do it right there in your node program.
Right now (in Oct 2012) the recommended way to do it is using a the socket.io-client library, which is available at https://github.com/LearnBoost/socket.io-client

Resources