Re: Understanding NSNetService and peer-to-peer streaming


Jack Brindle
 

One suggestion for testing on a single machine is to use VMware Fusion to create multiple macOS VMs. You will want a system with decent speed, but the environment should do exactly what you need with just one physical system.
Note that the current version of Fusion does not yet support High Sierra, so you will need to limit testing to Sierra and below.

- Jack

On Aug 20, 2017, at 7:00 PM, Graham Cox <graham@...> wrote:


On 18 Aug 2017, at 9:03 am, Graham Cox <graham.cox@...> wrote:

PS: What you're implementing sounds exactly like what the Multipeer Connectivity framework does. Are you aware of it? You could probably save yourself a ton of work by using it.
No, I’ve not heard of it. I did google for possible solutions, but it invariably finds a bunch of Stackoverflow questions, mostly without useful answers. I’ll check it out now I have a name to go by, though actually I’ve solved 90% of my problem and the remaining 10% is clear enough now.

This is a follow-up to my question last week.

I got my NSNetService + Streams approach more or less working, with one small problem (i’ll get to that).

But I also checked out Multipeer Connectivity (MC) and rolled a solution around that as well. The problem I’m running into with MC is that of testing it. While I have multiple devices to test it on, it’s very inconvenient to do that. I’d far rather test it on a single machine if possible. With the NSNetService design, it was quite happy to ‘see’ itself as another peer on the network, and allow a connection, making testing it on the one machine straightforward.

MC seems to go out of its way to prevent that, which on the surface makes sense, because in production you DON’T want your own machine to show up as a remote peer. But it makes testing it really hard. To try and work around it, I tried browsing and advertising using two different MCPeerID objects, with different names. That appears to work, in that the browser sees the advertised service on the same machine as another peer. Unfortunately, it completely fails after the discovery phase to actually connect. So I can test the discovery phase, but not the real meat of the thing, which is the communication.

Does anyone have any experience of MC and know how this can be made to work, or what are good approaches to testing, preferably on a single machine?

At this point the NSNetService design is functioning to a greater degree, because I can connect, even on the same machine. But the problem I’m having there is because it is stream based, I’m finding it difficult to implement something like MC’s message-based approach to communicating. If I send two ‘messages’ too quickly, they get concatented on the stream, and the receiver can’t tell where the boundary is between the two (or more) messages. So if I can solve that problem, it’s likely that the non-MC design will be the one to use, because it actually works in all other respects.

So, how to separate messages that just end up as a stream of bytes? I was thinking I could precede each one with a length field, which seems the simplest idea, assuming that I can be sure I can align the received stream to some sort of ‘frame’, so I can be sure the length field is where I think it is. But if you have any other clever ways, please share!

—Graham





Join cocoa@apple-dev.groups.io to automatically receive all group messages.