How do I send a message to a udp socket in Ruby 1.8.7 - ruby-1.8.7

I am able to send a message to a udp socket in Ruby 1.9x. I need to make this backwards compatible to Ruby 1.8.7, but I am not able to find any documentation on how to do this. Here's what I have for 1.9.x:
require 'socket'
socket = Socket.new(:INET, :DGRAM)
addr = Socket.sockaddr_in(UDP_PORT, UDP_HOST)
socket.connect_nonblock addr
socket.send(some_json_string, 0)
socket.close

This works in 1.8.7:
socket = UDPSocket.new
socket.send(payload, 0, UDP_HOST, UDP_PORT)
socket.close

Related

Unknown Output Characters in Arduino

I am actually connecting my laptop and arduino using FPVDrone 3DR Radio Telemetry. My connection is
ARDUINO tx- FPV Air module rx
ARDUINO rx- FPV Air module tx
ARDUINO 5v- FPV Air module 5v
ARDUINO GND- FPV Air module GND
while my FPV ground module is connected to my laptop. I have an app running using node JS with the following script
const SerialPort = require('serialport');
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort('COM3');
port.write('hello');
and my arduino code is
void setup() {
Serial.begin(57600);
}
void loop() {
if (Serial.available()) {
Serial.print((char) Serial.read());
delay(10);
}
}
i'm pretty sure they are communicating because my arduino is receiving some output, however the output is some characters i dont know,
arduino output
can someone please tell me what I should do so that i can receive the string "hello" to my arduino?
Try setting the baudrate in the node.js script
const port = new SerialPort(path, { baudRate: 57600 })
characters get messed up is the sending and receiving baudrates are different.
Are sure that the characters sent to the Arduino are ASCII code?
If you are sending integers and they are below 0x30, then they are non-printable characters and you will see gibberish.
Make sure that you send an ASCII symbol or use/make a terminal that can show the raw integers.

Why is socket.setNoDelay() throwing an error?

I have a nodejs server using socketio for real-time comms.
var app = require('http').createServer(handler)
, io = require('socket.io')().listen(app)
function init() {
app.listen(process.env.PORT || 8888);
};
io.sockets.on('connection', function (socket) {
socket.setNoDelay(true);
onSocketConnection(socket);
});
Issue is, every time I call socket.setNoDelay(true); it's kicking back:
E:[path]\server.js:58
socket.setNoDelay(true);
^
TypeError: undefined is not a function
at Namespace.<anonymous> (E:\[path]\server.js:58:12)
at Namespace.emit (events.js:107:17)
at Namespace.emit (E:\path]\node_modules\socket.io\lib\namespace.js:205:10)
at E:\[path]\node_modules\socket.io\lib\namespace.js:172:14
at process._tickCallback (node.js:355:11)
I can't seem to find any documentation as to why this is happening. Anyone else see this?
Specs:
> Windows Environment
> node version: 0.12.4
> socket.io version: 1.3.6
Because socket isn't a net.Socket, it's a socket.io Socket. You'll notice that there is no setNoDelay method on a socket.io Socket.
The socket.io websocket sever automatically disables Nagle on the underlying TCP socket.

firmatajs, multiple Arduinos give timeout (johnny-five, cylonjs)

I have two Arduino unos flashed with the standard StandardFirmata and i'm trying the multi board demo with a simple node project (johnny-five npm package). Both arduinos work when I try them separately. with the following code:
var five = require("johnny-five");
var boardOne = new five.Board({ id: "A", port: "/dev/cu.usbmodem1d1141" });
boardOne.on("ready", function(){
var led = new five.Led({
pin: 13,
board: this
});
led.on();
});
node index.js
1418288836782 Connected /dev/cu.usbmodem1d1141
1418288836784 Repl Initialized
>>
When trying the multi board example I get:
Device or Firmware Error A timeout occurred while connecting to the Board.
Please check that you've properly flashed the board with the correct firmware.
var five = require("johnny-five");
var ports = [
{ id: "A", port: "/dev/cu.usbmodem1d1141" },
{ id: "B", port: "/dev/cu.usbmodem1d1131" }
];
new five.Boards(ports).on("ready", function(){
var led = new five.Led({
pin: 13,
board: this[0]
});
led.on();
});
Update #1:
Out of curiosity I tried to switch around the usb cables and got some different results:
1) Only one arduino seems to connect:
1418318698635 Device(s) /dev/cu.usbmodem1a1231,/dev/cu.usbmodem1a1241
1418318698642 Device(s) /dev/cu.usbmodem1a1241
1418318701849 Connected /dev/cu.usbmodem1a1231
1418318701850 Board ID: A
or 2) I get an error:
.../johnny-five-master/node_modules/firmata/lib/firmata.js:246
board.pins[pin].analogChannel = currentValue;
^
TypeError: Cannot set property 'analogChannel' of undefined
at Object.SYSEX_RESPONSE.(anonymous function) [as 106]
(.../johnny-five-master/node_modules/firmata/lib/firmata.js:246:35)
Update #2:
I did the above test with cylon.js and got the same results. Still no clue how to fix this :(
One arduino works fine, multiple do nothing. (Maybe an osx related problem?)
Update #3:
I added some logs in the johnny-five code and it's definitely a connection problem(I think!?). The second Arduino never responds. I switched the order of the arduinos and get the same result (first one connects, the other fails to respond). The connection is asynchronous, so maybe it gets blocked somewhere. The lights on both arduinos definitely show some action is going on.
node index.js
err: undefined --- type: connect --- io: /dev/tty.usbmodem1d1111
err: undefined --- type: connect --- io: /dev/tty.usbmodem1d1121
err: undefined --- type: ready --- io: /dev/tty.usbmodem1d1111
1418467187527 Connected /dev/tty.usbmodem1d1111
1418467187527 Board ID: A
1418467284327 Device or Firmware Error A timeout occurred while connecting to the Board.
Please check that you've properly flashed the board with the correct firmware.
Thanks to #izar for posting this and then bringing the question to us in the Johnny-Five gitter channel. From there, Divan Visagie (from Johnny-Five core team) worked to triage the bug and was able to confirm via reproduction. This revealed a bug in Firmata.js, where the options passed to Serialport were being extended by that class. Since the defaults object was reused and Object.assign is not a "deep" operation, the changes were being made to a reference, not a copy. The result was that the second initialization was getting a set of "defaults" that were loaded up with the first instance's own data. The issue was fixed by changing Firmata to use fresh defaults for every instance. Here's the patch

Node js 0.10.7: cluster support for udp dgram?

I'm trying to run following node js application as mentioned https://github.com/joyent/node/issues/2194
var util = require("util"),
dgram = require("dgram"),
cluster = require('cluster');
var udp = dgram.createSocket("udp4");
var port = 1190;
if (cluster.isMaster) {
for (i = 0; i < 2; i++) {
cluster.fork();
}
} else {
util.log("starting udp server on port " + port);
udp.on("error", function (error) {
util.log("failed to bind to UDP port - " + error)
});
udp.bind(port);
}
The app exits immediately with the following output:
23 May 23:22:13 - starting udp server on port 1190
23 May 23:22:13 - starting udp server on port 1190
events.js:72
throw er; // Unhandled 'error' event
^
Error: write ENOTSUP - cannot write to IPC channel.
at errnoException (child_process.js:980:11)
at ChildProcess.target.send (child_process.js:455:16)
at Worker.send (cluster.js:401:21)
at sendInternalMessage (cluster.js:394:10)
at handleResponse (cluster.js:177:5)
at respond (cluster.js:192:5)
at Object.messageHandler.queryServer (cluster.js:242:5)
at handleMessage (cluster.js:197:32)
at ChildProcess.EventEmitter.emit (events.js:117:20)
at handleMessage (child_process.js:318:10)
Does anyone know what is going on? When running this without cluster, everything is fine.
It seems that cluster does not support udp?
Some specs:
Window 7 x64
node js 0.10.7
It says in the link your provided that support for UDP clustering was added in v0.11.14. It is likely that you simply need to update your version of node.js

Node.js, dgram.setBroadcast(flag) fails due to "EBADF"

I'm using Node.js 0.6.9, and am trying to send a datagram broadcast package. Code:
var sys = require('util');
var net = require('net');
var dgram = require('dgram');
var message = new Buffer('message');
var client = dgram.createSocket("udp4");
client.setBroadcast(true);
client.send(message, 0, message.length, 8282, "192.168.1.255", function(err, bytes) {
client.close();
});
Running the code:
$ node test.js
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: setBroadcast EBADF
at errnoException (dgram.js:352:11)
at Socket.setBroadcast (dgram.js:227:11)
at Object.<anonymous> (/home/letharion/tmp/collision/hello.js:25:8)
at Module._compile (module.js:444:26)
at Object..js (module.js:462:10)
at Module.load (module.js:351:32)
at Function._load (module.js:310:12)
at Array.0 (module.js:482:10)
at EventEmitter._tickCallback (node.js:192:41)
Some googling reveals that "EBADF" means "The socket argument is not a valid file descriptor". But I don't understand enough about the problem for that to be helpful.
First of all, you seem to have trouble understanding the format of the stacktrace, so let's clarify it before we go to the actual error that is thrown here.
Format of a node.js Stacktrace
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
This part is just the location where the internal NodeJS logic choked up and put out the error below:
The actual error stacktrace follows, it shows the deepest location in the callstack first, so going down in the stack trace, brings you up in the call hierachy, eventually leading you to the point in your code where everything began.
Error: setBroadcast EBADF
at errnoException (dgram.js:352:11)
at Socket.setBroadcast (dgram.js:227:11)
at Object.<anonymous> (/home/letharion/tmp/collision/hello.js:25:8)
at Module._compile (module.js:444:26)
at Object..js (module.js:462:10)
at Module.load (module.js:351:32)
at Function._load (module.js:310:12)
at Array.0 (module.js:482:10)
at EventEmitter._tickCallback (node.js:192:41)
First it fails in dgram.js on line 352, dgram.js is a internal node.js module abstracting the "low level" code. Line 352 is in a function containing generic logic for throwing errors.
It was called at dgram.js in line 227, after a failed if check which wraps the call to the wrapped native UDP sockets setBroadcast method.
Going up one more layer, we end up at your hello.js file on line 25 with the client.setBroadcast(true); call.
The rest is more node.js code resulting from the initial load of the hello.js file.
The actual Error
The error thrown by the native code which node.js wraps here is EBADF looking this up in conjunction with UDP gives us:
EBADF
The socket argument is not a valid file descriptor.
By going further down into the node.js rabbit hole, we end up in the udp wrapper, which wraps the uv wrapper for the actual C implementation, in the uv wrapper we find:
/*
* Set broadcast on or off
*
* Arguments:
* handle UDP handle. Should have been initialized with
* `uv_udp_init`.
* on 1 for on, 0 for off
*
* Returns:
* 0 on success, -1 on error.
*/
Leading us to the conclusion that your socket has not been initialized yet.
In the end, binding the socket via client.bind(8000) fixed the missing initialization and made the program run.
The method setBroadcast should be called on 'listening' event or passed as callback in bind method:
var socket = dgram.createSocket('udp4');
socket.on('listening', function(){
socket.setBroadcast(true);
});
socket.bind(8000);
OR:
var socket = dgram.createSocket('udp4');
socket.bind(8000, undefined, function() {
socket.setBroadcast(true);
});
It seems like the file descriptor is created only on bind or on send, and it's required before setBroadcast. You can call client.bind() with no parameter to bind to a random port before setting broadcast. Don't worry about using a random port, since it's done "lazily" when using client.send anyway.
var sys = require('util');
var net = require('net');
var dgram = require('dgram');
var message = new Buffer('message');
var client = dgram.createSocket("udp4");
client.bind();
client.setBroadcast(true);
client.send(message, 0, message.length, 8282, "192.168.1.255", function(err, bytes) {
client.close();
});

Resources