App-to-app communication on local network?

Looking for suggestions on solutions to allow two instances of my app running on phones on the same local wifi network to talk to each other and exchange data, without using any third-party paid service.

I tried NFC, but it seems NFC isn’t overly standard hardware. The second test phone I got doesn’t have it, so that was a deadend.

I tried Websocket Server. After a lot of headache I was able to get the server running on one phone but I have no idea how to discover and connect to it from the other phone. I tried having the client run ServiceDiscovery first to try and find it but I’m not super familiar with the service type parameter it wants and the “ssdp:all” given in the example didn’t return anything that looked like my service. So this might be a viable avenue but I’m currently at a wall with it.

I guess the next thing to try is Bluetooth?

Hopefully someone has some suggestions. I’m really surprised at how complicated this has become, given how simple it should be on paper.

I haven’t actually done this, but if I were in your situation, I would stick with the websocket idea and use zeroconf instead of “servicediscovery”.

Thanks, this looks like exactly what I needed. And the documentation was correct and worked first try. Looks like I won’t even need the Websockets with this.

Only little hiccup after putting in the documented example is that the watcher isn’t getting the same data as is being registered. Maybe you’ve experienced this and know the answer? I haven’t dug into it yet.

Caller

Service registered 
domain:"local."
hostname:"android-6ce65a0b8398af9d.local."
ipv4Addresses:["192.168.1.133"]
ipv6Addresses:[]
name:"Becvert's iPad"
port:80
txtRecord:{foo: "bar"}

Watcher

Service added 
domain: "local."
hostname: "Becvert's iPad._http._tcp.local."
ipv4Addresses: []
ipv6Addresses: []
name: "Becvert's iPad"
port: 0
txtRecord: {Becvert's iPad._http._tcp.local.: "true"}

Nevermind, figured it out. Once I dug into the documentation I saw there’s actually two steps to the watch process, the discovery and then the resolve, and it’s not until after the resolve that the data is populated. Looks all set now. Thanks again!