Audio transfer android and node-webkit - javascript

I have been trying to transfer audio files between my android app and my node-webkit app but I'm new to the world of socket.io/nodejs/delivery.js.
Here is my code:
android-code ERROR-LINE: os.write(mybytearray, 0, mybytearray.length);
protected Void doInBackground(Void... arg0) {
Socket sock;
try {
// sock = new Socket("MY_PCs_IP", 1149);
sock = new Socket("192.168.0.10", 5001);
System.out.println("Connecting...");
// sendfile
File myFile = new File(this.currentSong.getPath());
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
System.out.println("Sended..");
// RESPONSE FROM THE SERVER
BufferedReader in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
in.ready();
String userInput = in.readLine();
System.out.println("Response from server..." + userInput);
sock.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
node-webkit-code
var io = require('socket.io').listen(5001),
dl = require('delivery'), //delivery.server
fs = require('fs');
io.sockets.on('connection', function(socket){
delivery = dl.listen(socket);
delivery.on('receive.success',function(file){
fs.writeFile("music/"+file.name,file.buffer, function(err){
if(err){
console.log('File could not be saved.');
}else{
console.log('File saved.');
addSong("music/"+file.name);
};
});
});
});
Note: My server side works well it's already tested by a js client
This is the error I am getting:
Android side Error:
08-28 14:56:36.180: W/System.err(30510): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
08-28 14:56:36.180: W/System.err(30510): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:499)
08-28 14:56:36.180: W/System.err(30510): at libcore.io.IoBridge.sendto(IoBridge.java:468)
08-28 14:56:36.180: W/System.err(30510): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
So maybe I'm wrong trying to do a bad connection because of protocols.. between a socket and socket.io..?
if any one can help my out I will be pleased. I already looked around but as I said I'm new to this world and I get hazy
basically my question is: What's wrong? and How I accomplish my objective?
Thanks for your time

I am using com.koushikdutta.async.http.socketio.SocketIOClient
there is some problems with this library and socket.io but it it's solved by using this dependency on node-webkit
"socket.io": "~0.9",
also need to read file->base64 codification-> then emit the string on the server side must do this:
socket.on('finishFileTransfer',function(){
fs.writeFile("music/"+fileName,new Buffer(file,'base64'), function(err){
if(err){
console.log('File could not be saved.');
}else{
console.log('File saved.');
addSong("musica/"+fileName);
}
file = "";
fileName = null;
});
});

Related

Why does netcat work just fine when using my listener but it doesnt work when I use JS

I wrote a C# listener that listens on a port and prints everything it recieves, and it works perfectly but when i used a JS client to send that data something get recieved but nothing gets written to the console
My C# code:
while (true)
{
TcpClient client = null;
NetworkStream stream = null;
try
{
client = listener.AcceptTcpClient();
stream = client.GetStream();
using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII) { AutoFlush = false })
{
using (StreamReader reader = new StreamReader(stream, Encoding.ASCII))
{
while (true)
{
string inputLine = "";
while (inputLine != null)
{
inputLine = reader.ReadLine();
Console.WriteLine(inputLine);
Console.WriteLine(Encoding.UTF8.GetString(Encoding.ASCII.GetBytes(inputLine)));
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (stream != null)
{
stream.Close();
}
if (client != null)
{
client.Close();
}
}
Console.WriteLine("Verbinding met client verbroken");
}
const net = require('net');
const client = new net.Socket();
client.connect(1234, '192.168.2.13', () => {
console.log('Connected to server');
client.write("Hello server\r");
});
I tried running a netcat listener and that worked with my JS program, I also set breakpoints in my code and concluded that when i send something with my JS code it indeed gets recieved by my server but not processed.
Your server/listener tries to read a complete line ('reader.ReadLine()').
This means, your JS client must send some "line end" marker. "Line end" is newline '\n' (although documentation specifies apparently non-working alternatives).
So socket.write("Hello server\n") should work.

Send blob via websocket cause page reload

I'm trying to send recordRTC blob via websocket to my Java server, my goal is to build a video stream service.
However, when the server received the blob, and write file, the web page would refresh, cause recordRTC stopped and socket disconnct.
Used package
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.4.0</version>
</dependency>
The following is my code.
Server side
public void onMessage( WebSocket conn, ByteBuffer message ) {
byte[] bytes = new byte[message.remaining()];
message.get(bytes, 0, bytes.length);
if(bytes.length > 0) {
OutputStream os = null;
UUID uuid = UUID.randomUUID();
String id=uuid.toString();
String filename =id.replace("-", "");
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(
new File("./uploads/"+filename +".webm")));
bos.write(bytes);
bos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client side
function startCapture() {
logElem.innerHTML = "";
try {
videoElem.srcObject = navigator.mediaDevices.getDisplayMedia(displayMediaOptions).then(
(stream)=>{
console.log(stream);
recordRTC = RecordRTC(stream);
recordRTC.startRecording();
// blob segment and send every 3 second
recording = setInterval(()=>{
recordRTC.stopRecording(()=>{
console.log("BLOB : ", recordRTC.getBlob());
recordRTC.getBlob().arrayBuffer().then((val)=>{
console.log("BLOB : ", recordRTC.getBlob());
socket.send(val);
});
})
recordRTC.startRecording();
}, 3000);
videoElem.srcObject = new MediaStream(stream);
});
} catch (err) {
console.error("Error: " + err);
}
}
reload event picture
I found the reload EVENT occur after the fisrt blob sent and write to file, but I don't know why the event happend.
If server don't write blob to file, just receive it, the websocket and web would work perfectly without reloading.
How could I solve the reload EVENT problem?
Thanks

Can't send data from Java Socket Server to NodeJS client

I'm making a live connection between a Socket Server (Java) and a Socket Client (NodeJS). This is for a webinterface.
I can send data from NodeJS to Java, but not the other way around. I commented in the code, which positions I mean. I tried it already like you see with out.write("Hello World\n"); (with flush, of course). I tried also with out.println("Hello World"); (with flush, of course).
public class WebHandler {
private ServerSocket server;
private static Socket sock;
public void listen(int port) {
try {
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not listen on port " + port);
System.exit(-1);
}
Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new BukkitRunnable() {
#Override
public void run() {
try {
System.out.println("Waiting for connection");
final Socket socket = server.accept();
sock = socket;
final InputStream inputStream = socket.getInputStream();
final InputStreamReader streamReader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(streamReader);
// readLine blocks until line arrives or socket closes, upon which it returns null
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
WebHandler.sendMessage();
} catch (IOException e) {
System.out.println("Accept failed: " + port);
System.exit(-1);
}
}
}, 0, 100);
}
// CRITICAL
public static void sendMessage() {
try {
PrintWriter out = new PrintWriter(sock.getOutputStream());
out.write("Hello World from Java!" + "\n");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
var net = require('net');
var client = net.connect(9090, 'localhost');
client.setEncoding('utf8');
setInterval(function() {
console.log("Writing....")
var ret = client.write('Hello from node.js\n');
console.log("Wrote", ret)
}, 5000);
// CRITICAL
client.on('data', function(data) {
console.log('Received: ' + data);
});
Please don't let you distract because of the Bukkit.getScheduler()... It's only a Task Manager. Thanks in advance :D
You don't receive a message from java because you have set an interval which will always send messages to the server and the server will be stuck in the while loop.
I would suggest to stop the interval at some point so that sendMessage() will be called.

How to send message from node.js server to Android app?

Im trying to make a simple application. That is When I write a word at edittext in android app such as "Hi", Then android app send message "Hi" to node.js server and node.js server send message "Hi has sent successflly" to android app. This is just a example, actually my object is android send a data(message) to server, and receive another data(message) from server.
The problem is this. When I write a word at android app and press button, the message transmitted successfully(I can confirm by console at node.js). But I cant send message to android from node.js .. When I press send button, My android app shut down..
What android says is "java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Activity.runOnUiThread(java.lang.Runnable)' on a null object reference" ..
Yesterday, this error didn't happened and another error occured. "cannot cast string to JSONObject."
I will show you my code.
Server Side(Node.js)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = 12000;
app.get('/', function(req, res) {
res.sendFile('index.html');
})
io.on('connection', function(socket) {
console.log('Android device has been connected');
socket.on('message', function(data) {
console.log('message from Android : ' + data);
Object.keys(io.sockets.sockets);
Object.keys(io.sockets.sockets).forEach(function (id) {
console.log("ID : ", id );
io.to(id).emit('message', data);
console.log(data + ' has sent successfully');
})
/*if (data != null) {
io.emit('message', {message : data + ' has received successfully'});
}*/
})
socket.on('disconnect', function() {
console.log('Android device has been disconnected');
})
})
http.listen(port, function() {
console.log('Server Start at port number ' + port);
})
Client Side (Android)
private Emitter.Listener handleIncomingMessages = new Emitter.Listener(){
#Override
public void call(final Object... args){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject) args[0];
String message;
try {
message = data.getString("text").toString();
Log.i("result", message);
addMessage(message);
} catch (JSONException e) {
Log.e("result", "Error : JSONException");
return;
} catch (ClassCastException e) {
Log.e("result", "Error : ClassCastException");
e.printStackTrace();
return;
}
}
});
}
};
private void sendMessage(){
String message = mInputMessageView.getText().toString().trim();
mInputMessageView.setText("");
addMessage(message);
JSONObject sendText = new JSONObject();
try{
sendText.put("text", message);
socket.emit("message", message);
}catch(JSONException e){
}
}
private void addMessage(String message) {
mMessages.add(new Message.Builder(Message.TYPE_MESSAGE)
.message(message).build());
// mAdapter = new MessageAdapter(mMessages);
mAdapter = new MessageAdapter( mMessages);
mAdapter.notifyItemInserted(0);
scrollToBottom();
}
private void scrollToBottom() {
mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
}
I already searched similar problems that other people asked, but It didn't give me solution. Please help me. Thank you for reading long question.
p.s Because Im not English speaker, Im not good at English .. There will be many problems at grammar and writing skills. Thanks for understanding...
Reason this happens is because method getActivity() returns null. This might happen if you run this on a fragment after it is detached from an activity or activity is no longer visible. I would do a normal null check before like:
Activity activity = getActivity();
if(activity != null) {
activity.runOnUiThread(new Runnable() {...}
}
I'm not familiar with socket.emit() method but it might throw network exception since it's running on UI thread and you are not allowed to do that. I recommend using RxJava/RxAndroid if you want to do this on another thread.
If you want to do network operation just use it like this:
Observable
.fromRunnable(new Runnable {
void run() {
// here do your work
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Void>() {
#Override
public void onCompleted() {
// not really needed here
}
#Override
public void onError(Throwable e) {
// handle errors on UI thread
}
#Override
public void onNext(Void void) {
// do something on UI thread after run is done
}
});
Basically what it does it calls method call from Callable you just made on separate thread and when it's over it invokes onNext method if no exception was thrown or onError method if exception was thrown from Subscriber class.
Note that Response class isn't part of the RxJava/RxAndroid API and you can make it if you want. You can make it a simple POJO class or anything else you need it to be. If you don't need to have response you can use Runnable instead of Callable and it will work just fine.
In order for this to work you need to add this dependencies to your modules Gradle file:
dependencies {
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.6'
}

Nodejs to Android Rar (image file) Send

I want to send image Node.js server to Android Clients.
I am using a REST Service between Node.js and Android Devices.
I can send image using node.js module 'fs' and receive Android device.
It's ok but i have over 200 images and each image's size between 1KB and 2KB. It' s very small images. So i dont want to send one by one. Its too slow so i am curious about if i ".rar" all image file (about 2MB), can i send one time and show images in android devices?
Or are there any way to send one time without ".rar" ?
Of course you can compress them in an archive(any kind) and decompress them on the device.
Using nodejs-zip you can generate zip archives. An example of compression (taken from here)
var http = require('http'),
nodejszip = require('../lib/nodejs-zip');
http.createServer(function (req, res) {
var file = 'compress-example.zip',
arguments = ['-j'],
fileList = [
'assets/image_1.jpg',
'assets/image_2.jpg',
'assets/image_3.jpg',
'assets/image_4.jpg',
'assets/image_5.jpg',
'assets/image_6.jpg',
'assets/image_7.jpg',
'assets/image_8.jpg',
'assets/image_9.jpg',
'assets/image_10.jpg',
'assets/image_11.jpg',
'assets/image_12.jpg',
'assets/image_13.jpg',
'assets/image_14.jpg'];
var zip = new nodejszip();
zip.compress(file, fileList, arguments, function(err) {
if (err) {
throw err;
}
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Complete.\n');
});
}).listen(8000);
On the device you can decompress a zip archive like that.(taken from here)
public class Decompress {
private String _zipFile;
private String _location;
public Decompress(String zipFile, String location) {
_zipFile = zipFile;
_location = location;
_dirChecker("");
}
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}

Categories