tradle / react-native-udp

node's dgram for react-native
MIT License
339 stars 154 forks source link

Support - recommended way to read in udp #32

Closed ORESoftware closed 7 years ago

ORESoftware commented 7 years ago

I am pretty new to react-native and also developing for mobile; I need to listen for UDP messages by connecting to the local internet (nearest wifi router)

I assume my device (Android) will have wifi connectivity If I listen for udp on a port, I should get data, right?

I am developing for Android - just curious why there is so much less Java than Objective-C for this project?

Objectively speaking, is this the best module to use for the job of listening for UDP messages coming via a local wifi router?

sorry for super naive questions but trying to figure this outt

ORESoftware commented 7 years ago

also, when I ran the commands as listed in the readme.md

https://github.com/tradle/react-native-udp/blob/master/examples/rctsockets/android/app/src/main/java/com/rctsockets/MainApplication.java#L11

the lines mention above were already added to my .java files, that was magic, why did that happen? :) I mean I guess that's good, never seen people modify java source like that!

ORESoftware commented 7 years ago

Ok more practical question:

I have this code in a test script:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

server.on('listening', () => {
  var address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(12345);

setInterval(function(){
   server.send('abc', 0, 3, 12345,'localhost', function(err){
          console.log('message sent.');
   })
}, 3000);

and then in my Android React-Native code, I have:

const Buffer = global.Buffer = require('buffer');
const dgram = require('dgram')
const socket = dgram.createSocket('udp4');

socket.bind(12345);

socket.on('error', (err) => {
  console.log(`socket error:\n${err.stack}`);
});

socket.once('listening', function() {
  console.log('listening!!');
})

socket.on('message', function(msg, rinfo) {
  console.log('message was received', msg);
    socket.send('def', 0, 3, 12345,'localhost', function(err){
            console.log('message sent.');
     });
});

export default socket;

as you can see, both UDP socket servers are bound to the same port, and I don't see any errors - but I am not getting any messages in my Android log files.

Any idea why the following setup would mean that my React Native code would not receive UDP messages?

The good thing is that my test script server is receiving its own messages (it's sending messages out to any services listening on its own port). Since I do not set exclusive:true, it seems like we can bind more than one service to a port.

ORESoftware commented 7 years ago

Btw I tried having each UDP server listen on a different port, and that didn't make a difference. My React-Native UDP server still does not receive any messages from the test script server.

mvayngrib commented 7 years ago

@ORESoftware thanks for raising this. I tried your setup and reproduced your results. I think it's cause the emulator has its own ip address, or rather the VM that runs it. There's some port forwarding going on as you can see. I got them connected in three steps:

  1. in index.android.js, set the local IP of your machine, in my case 192.168.1.7:
    socket.send('def', 0, 3, 12346, '192.168.1.7', function(err) {
  2. run the test script and emulator. In the test script, I started getting messages like this:
    server got: u� from 192.168.1.7:65523

    notice the forwarded port, 65523

  3. I then changed the test script as follows:
    server.send('abc', 0, 3, 65523, '192.168.1.7', function(err){

and then there was magic, see below:

image

mvayngrib commented 7 years ago

@ORESoftware Q: I am developing for Android - just curious why there is so much less Java than Objective-C for this project? A: the amount of code authored in this module is about the same for Obj-C and Java, but the Obj-C end imports the GCDAsyncUdpSocket library from CocoaAsyncSocket

Q: Objectively speaking, is this the best module to use for the job of listening for UDP messages coming via a local wifi router? A: objectively speaking, I only know of this module for using UDP sockets in react-native

ORESoftware commented 7 years ago

thanks for the info, very useful, shared it with my team, thanks again