Open ghost opened 4 years ago
Hi @c-thun Hm, in fact it looks like a race condition.
You are trying to send multiple files at the same time (that's how forEach
works) - it's not correct.
In receiveFromClient
function you receive only one file.
In case if you want to send multiple files you should do it sequentially: file1 -> file2 -> file3 (only after successful transfer of file1
you start transfering file2
).
I hope I gave you an answer on your question why it's not working. Try to rewrite your code and send files sequentially. Feel free to ask other questions if something is not clear :)
So if i try and send one file, it should work, right?
However, that still doesn't seem to explain why calling createGroup()
is failing in the receiver side. Also, thanks for pointing that out. I had totally forgotten the race condition issue so will rectify that.
Upon testing with one file only (to prevent for the issue of race condition), I still get the same error. The exact same error.
I can see that sendFile()
may have an issue because the file path is something like this "content://com.android.providers.media.documents/document/image%3A217" and you mentioned in another issue that this can be a problem. However, even in this case, sendMessage()
should work by commenting out the rest. Also, the server should be able to create a group but that isn't happening either as mentioned above.
Any help, insight, etc would be helpful. I can give you exact logs from whatever source you want so if you need me to provide any such, do ask and I would be happy to provide you the details so that this issue can be fixed
Hi, @c-thun
However, that still doesn't seem to explain why calling createGroup() is failing in the receiver side.
That would be nice if you can share your logs from adb logcat
. Please, attach them as *.txt file.
You described your issue, and I understand what is the problem. And, of course, this problem shouldn't exist. So attaching Android logs (Java) can help me significantly :)
BTW, have you tried to switch you server/client devices? I mean run client code on "server" phone, and "client" code on server device? Merely change roles of devices. In this case you still receive the same error?
I did change the roles of the devices multiple times but it didn't do anything different except for once when it did actually manage to send a message to the other device. Other than that one transmission, it didn't work regardless of which device was client and which was server.
Will attach the ADB Logcat response in a few hours (away from my laptop right now)
Here is the ADB Logcat. Steps done in sequence : -
In addition, for some reason it shows a FINE_LOCATION issue in adb logcat but I have provided both
As I see from logs the internal variable wifip2pInfo
is null
. Why are you calling getAvailablePeers
?
BTW, I don't see successful execution of getConnectionInfo
https://github.com/kirillzyusko/react-native-wifi-p2p/blob/102e00508501ad32aeaca0b651312170c4f129d8/android/src/main/java/io/wifi/p2p/WiFiP2PManagerModule.java#L63
getAvailablePeers()
was called only as a debugging step to confirm if it was actually seeing the other device or not. The logcat output after removing the line are attached below. Also, I used console.log(devices)
in subscribeOnPeersUpdates()
to confirm if there actually are devices nearby. Attaching that as well.
Also, you are right that getConnectionInfo()
is failing
adb_output.txt
Trying after reversing the devices, here are the adb logcat files after reversing the devices roles.
Also, I got a doubt. createGroup()
always fails as it says that the framework is busy. Could it be because subscribeOnPeersUpdates()
is always running in the background and preventing createGroup()
from using the WiFiP2P service? If that is the case, I can unsubscribe before calling createGroup()
and try
Also, I got a doubt. createGroup() always fails as it says that the framework is busy. Could it be because subscribeOnPeersUpdates() is always running in the background and preventing createGroup() from using the WiFiP2P service? If that is the case, I can unsubscribe before calling createGroup() and try
I don't think so.
In fact I found the same problem. Try to find 01:49:44.409 from previous log. What was this command? createGroup? Have you checked - maybe group already was formed?
BTW, what type of debugging do you use? Through WiFi or through USB cable? (If you are debugging/downloading bundle via WiFi - please, try to switch to cable method).
I'm asking because I see SoftException
from RN straight after the line that I mentioned (It's about WebSockets).
The one on 01:49:44.409 is the output that is caused by problems in the startDiscoveringPeers()
method. This one actually would have happened because the app crashed during sendMessage()
and upon reload, was not able to even start discovering the peers properly. I needed to force close the app and reload it from scratch to get it working normally. So, this output was post crash
Also, I am using USB cable (that came with the phone's charger) to debug the app. The soft exception would have been due to the crash I suppose.
Also, wherever I have called createGroup()
, I have now ensured that on successful creation, it will do a
console.log('Successfully created group')
. As I have not seen any such outputs on console regarding successful group creation even once, the only thing I can assume is that createGroup()
has never run successfully for me.
Any updates?
One interesting moment:
Calling JS function after bridge has been destroyed: RCTDeviceEventEmitter.emit(["WIFI_P2P:PEERS_UPDATED",{"devices":[{"status":1,"isGroupOwner":false,"secondaryDeviceType":null,"primaryDeviceType":"10-0050F204-5","deviceAddress":"82:58:f8:25:e0:01","deviceName":"Android_819e"}]}])
Why bridge has been destroyed? :) It happens before actual sending.
Another moment:
08-19 01:49:33.109 674 1086 D WifiP2pService: Client:com.meridio is removed
08-19 01:49:33.110 674 1086 D WifiP2pService: Client:com.meridio is removed
Why it removes two times?
In adb reverse:
08-19 01:56:58.512 16570 18232 W ReactNativeJS: Cannot connect to the Metro server.
Why so?
I don't see any direct errors, to be honest... Could you edit your code in node_modules
and add more Log.i
statements? I don't know why getConnectionInfo
failing...
Also I don't see Successfully created group
.
I know, my answer probably will not help you, since I don't know what is going wrong...
So you mean adding more log statements in react-native-wifi-p2p
package?
And yes, I am never able to create group despite following the exact same order that was in your documentation. Can the issue here also be caused by the fact that I'm using a rooted phone with a custom ROM? If yes, then I can retry running the code after reverting the devices to the OEM builds (I'm not sure why this would cause an issue but custom ROMs can sometimes have missing implementations of features)
So you mean adding more log statements in react-native-wifi-p2p package?
Yes, it may be useful to see, where the errors occur. You can try to wrap the body of getConnectionInfo
in try/catch
statement and see, what error emerges there. I think it can be useful.
And yes, I am never able to create group despite following the exact same order that was in your documentation. Can the issue here also be caused by the fact that I'm using a rooted phone with a custom ROM? If yes, then I can retry running the code after reverting the devices to the OEM builds (I'm not sure why this would cause an issue but custom ROMs can sometimes have missing implementations of features)
It can be, however I'm not sure...
So it's definitely not due to the custom ROM. I reverted to the stock firmware and it still is not able to create the group. Maybe I can go for the suboptimal solution of connecting via QR codes and then sharing via TCP for now but would have really loved this to work. I'm completely stumped why this doesn't work.
If you feel like, I can open source my app repo and you can take a look? Maybe you'll find some issues over there. Also, if you have time and are willing to collaborate, you could join in as a contributor to the app I'm making. If we can make it work with your API, then it can be a really nice Proof of concept for your library. I'm honestly in a slump right now and any help would be immensely helpful 😢
@c-thun have you tried use this repo: https://github.com/kirillzyusko/react-native-wifi-p2p-example Maybe you made a mistake in the integration this library into your project? I really want to help you. So, please, try to reproduce your problem using this repo. If you still will not be able to create group even in this repository - I really don't know, how to help you. Maybe only a call/screen-sharing-session with you may help us. I will tell you what you can change and we will see how it affects.
That was one of the first things I did and, if I recall correctly, even then I was not able to create group and it showed the same error even then.
Code 2 : Resource is busy
I can try it once more today but if it doesn't work, I'll probably ask my friends to try my app on their devices (maybe it turns out to be a hardware issue) and the if even that works, I might probably have to just resort to the QR based solution. Thanks a lot for the help though.
You can read more about error: https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager#BUSY
It's system Android error. So the search in the internet may also give you some useful insights.
Just try to search busy wifi p2p create group
in google :)
And yes, try on other devices.
I hope you will be able to solve this issue.
For sure, will look into it in some time. Do keep the issue open, if there is some update that helps me fix this issue, then I can let you know and hopefully this can help others who face this issue too.
So, I managed to overcome the issues of creating group by calling a remove group first. However, this only worked with one device and didn't work with the other (for some weird reason). In addition, while I'm trying to send files, I'm getting this error (attached)
Good. At least one device now can create group successfully. The error seems to be the same as before. So I have to ask: did you call getConnectionInfo
? Was the execution of this function successful?
So, as you can see in the picture, the console output Getting connection info occurs while I'm calling getConnectionInfo()
so that's happening successfully (atleast on one device). The error occurs while sending file using sendFile()
. Have a look at the modified code and see if you can spot any errors in the flow
import * as WiFiP2P from 'react-native-wifi-p2p';
const sendFiles = (files) => {
const nextFile = files.shift();
if (nextFile) {
console.log('Sending file ', nextFile.name);
return WiFiP2P.sendMessage(nextFile.name).then(WiFiP2P.sendFile(nextFile.uri)).then(_ => WiFiP2P.sendFiles(files));
} else {
return Promise.resolve();
}
}
export const sendFilesToServer = (macAddr, files) => {
console.log(files, macAddr);
files.forEach(file => {
WiFiP2P.connect(macAddr)
// Resolve connection details using getConnectionInfo
.then(() => WiFiP2P.getConnectionInfo())
.then(() => {
console.log('Sending Files');
return sendFiles(files);
})
.catch(err => console.log('Error occurred', err));
});
}
export const receiveFromClient = () => {
console.log('Can receive now');
// Receive file metadata using receiveMessage()
WiFiP2P.removeGroup(() => console.log('Removed old group'))
.then(() => {
console.log('Successfully created group');
return WiFiP2P.createGroup();
})
.then(() => {
console.log('Waiting for message');
return WiFiP2P.receiveMessage();
})
// .then(() => {
// return PermissionsAndroid.request(
// PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
// {
// 'title': 'Access to write',
// 'message': 'WRITE_EXTERNAL_STORAGE'
// }
// )
// })
// Receive file and store it based on the metadata
.then(message => {
console.log('Received message ', message);
return WiFiP2P.receiveFile('/storage/emulated/0/Music/', message);
})
.catch(err => console.log(err));
}
Ooops, sorry, didn't notice it. Could you attach adb logcat output then?
But I can try to say in advance where is the problem :)
You have %3A
in you path .../msf%3A14
. As I described in https://github.com/kirillzyusko/react-native-wifi-p2p/issues/26 such symbols should be properly encoded.
In your case it should be .../msf:14
. Not .../msf%3A14
.
So how do I encode them? Do I parse through the string and modify it or is there any built in library that can be used for the same?
Try to use this package. Or try to search in google how to encode/decode URI. Maybe you could find better way :)
I'm using encodeURI
in browsers. Not sure whether this method is available in react-native.
But at the beginning you can "hardcode" this path. Just for checking whether my suggestion is working in your case or there are others problems as well. And if it works - try to find a long term solution :)
So, I did the decodeURI
thing, as you will be able to see in the screenshot attached. Also, see what the output of getConnectionInfo()
gives. So, clearly it is able to detect the group and attempt to connect to it. However, actually connecting is where the issue is happening (in the sendMessage()
and sendFile()
functions)
Okay, then output from adb
should help :)
Here it is
Did you miss a callback inside of promises chain? Instead of:
return WiFiP2P.sendMessage(nextFile.name).then(WiFiP2P.sendFile(nextFile.uri)).then(_ => WiFiP2P.sendFiles(files));
Shouldn't be:
return WiFiP2P.sendMessage(nextFile.name).then(() => WiFiP2P.sendFile(nextFile.uri)).then(_ => WiFiP2P.sendFiles(files)/*not sure, that method exist in my API :)*/);
?
Oops, I certainly missed the callback. Thanks for pointing that out. However, while correcting that mistake certainly helped remove the unnecessary error that was there because of the Promise chain, it still didn't resolve the ECONConnectionRefused thing. Here is how the thing looks after correcting for the callback and only that change. Also, thanks for pointing that out. It wasn't your function. Renamed it as well. However, the connection refused error persists
Also, find attached the ADB Logcat output
Now you are trying to send two files. It will not work. sendFile opens socket connection. And since you are trying send two files - second connection will be rejected because the port is already in usage. It's happening because you are sending files via forEach. And it sends files in parallel. But you should do it sequentially. Also connect and getConnectionInfo should be called not inside of for-loop. Try to send one file. I can assure, that it will work. Or try to send one message (without file). I also can assure that it will work perfectly.
The sendFiles method that I have created will do it sequentially (I forgot to remove the for loop earlier. Fixed that) by recursively calling the sendMessage and sendFile functions only after the previous succeed. In addition, I've tried sending only one file but the same issue persists
In addition, I've tried sending only one file but the same issue persists
Could you attach logs from this case? Also try to change your devices roles (if 1st device was responsible for sending and 2nd for receiving, try to send file from 2nd and receive on first. It may help. And keep things simple - try to send only messages. Without files.)
Tried both of your recommendations. Here is the attached log file. If you feel like, you may view my app code (I made the repo public)
Here it is : https://github.com/c-thun/meridio
You will see two send cases in the adb logcat. I am trying to only send the message this time (regardless of the console output) and the first time, I send the name of one file as a message only while the other time I send the name of two files
And the logs attached below (output_twiceAgain.txt) is the logcat output when I just directly use sendMessage()
as follows
WiFiP2P.connect(macAddr)
// Resolve connection details using getConnectionInfo
.then(() => {
console.log('Getting connection info');
return WiFiP2P.getConnectionInfo().then(info => console.log('getConnectionInfo', info));
})
.then(() => {
console.log('Sending Files');
// return sendFiles(files);
return WiFiP2P.sendMessage('Hey ya');
})
.catch(err => console.log('Error occurred', err));
And try to receive the message on the other device. I also tried this after reversing the roles to no avail
I will try to run your repo on my phones.
By some random method : One device did manage to send a Hey message to the other (I saw it received on the second device) but that so far has just been an anomaly. Unable to reproduce it
Any updates?
@c-thun Still haven't had a chance/free time to test it... Too busy with main work, unfortunately :(
No worries. With Nearby Share being pushed out to all android users, my project no longer is time constrained and has become more of a enthusiast learning endeavour. Take your time. I am also between projects currently :)
@c-thun By the way, did you consider to try to use nearby API?
I didn't know this API was there. This sounds perfect. I'll try this out asap. Thanks a lot
Repeatedly getting this while using sendMessage() and sendFile(). My code is as follows -
EDIT : In addition, whenever the server tries to run
createGroup()
, it always returns with the error as follows{ "code" : 2, "message": "Operation failed because the framework is busy and unable to service the request" }