InterprocessConnection timeout after creation

Hi, I’m trying the InterprocessConnection. I’m right at the beginning and I’ve already made a mistake, it seems.

When I call createPipe() in my inherited class it works fine, but after Timeout time it calls connectionLost(), and I don’t know why. It’s just creating a pipe and doing nothing else, and there is no other instances running, it’s just calling createPipe on it’s own. Why is the pipe almost instantly getting lost?

If I put timeoutMs as -1 then it’ll hang if I try to send messages and it’s the only one open. ( but that’s another problem )

What’s the call stack look like when connectionLost() is called?

I’m away from the computer but I just guess you can’t have a open pipe, as it always has to connect to something. So a keep trying thread would suit this situation - occasionally looking for others or creating one if there is none?

BTW, when connected everything worked really well. Nice work, juce!
DaveH.

I’m not sure I understand the first sentence. Per the createPipe() docs, This creates a pipe with the given name, so that other processes can use connectToPipe() to connect to the other end.. So, you should be able to have an open pipe with nothing connected to it. Which is not true for connectPipe(), as it requires one to exist already.

@ cpr2323
Hmm, yes that’s odd.
I need to be clearer about what I’m looking for.
The idea is every instance of a plug-in can broadcast to every other instance, so each instance can send messages to all all instances. It doesn’t have to be fast, and it’s a small amount of info that is sent - when one changes a parameter I want them all to receive the change (in a compact format, I haven’t decided yet)

I’m thinking the pipe won’t work as it appears to be a one-on-one situation?

So sockets it is then. Can each instance be a potential master and slave at the same time? I need the master instance to be able to send messages, and I haven’t seen examples of this working.
Can anybody help, or even just a hint if it’s possible?
Thanks.

Interesting, I’m working on something similar, although I’m making it a bit more complicated (but hopefully also really flexible and awesome).

Yep I think you need sockets to do the one-to-many things. If each instance is both server and client, you’ll have a hard time to coordinate how they connect (e.g. port numbers). One has to be coordinator, either with all communication running through that instance, or with the coordinator facilitating how other instances connect to each other directly.

What I’m planning to do is this:

  • When an instance is loaded, it tries to open a socket with a standard port number. If it works, it seems to be the first to try, so it becomes coordinator
  • Subsequent instances connect to the coordinator and run communications through it
  • When the coordinator instance closes, all connections are closed
  • If other disconnected instances remain, after a short timeout they try to either become the new coordinator, or connect to whatever instance was faster trying that

It’s probably smart to synchronize the connection stuff with an InterProcessLock.

That said, you can get away with something much more simple if all instances are on the same process, which is the case for most hosts. Then you can just have some shared memory scheme or something where instances can discover each other and get object pointers to use. But it won’t work e.g. in Bitwig which has a mode where each plugin instances can get its own process.

What I’m working on is a hybrid approach. Instances within the same process can communicate much more directly, while some inter-process connection is used to tunnel communication between different processes.

I tried putting a ‘slave’ (gawd I hate that name) on the master in @daniel 's code from here:

But the master didn’t send messages to the slave, it could only send them to itself it seems. The slave didn’t received any messages from it.
So I got it all working except the master can’t send message to others yet.

Crazy indeed how perception changed over the last 6 years. I wouldn’t use that terms today, at least not without trying to use a different wording. So my apologies for my ignorance back then.

FWIW, I never had good results with pipes on windows, so I usually resorted to sockets instead.

1 Like

FWIW, I never had good results with pipes on windows, so I usually resorted to sockets instead.
@ daniel

Thanks that’s very useful. Is there a way for the server to send messages to all others. Did you get that working at all?

I don’t think a broadcast would work. But no problem to iterate the InterprocessConnections and call sendMessage() on each.
Remember it is a tcp socket, so there is a handshake going on, which contradicts a broadcast approach as I understand it.

Would that work for you?

@ daniel
Hmm, by iterate, do you mean each instance has a different port address server on each?

If that’s so, I’ll need a way of searching what is running, I could potential have dozens or more.

I don’t think you need to.
When you inherit InterprocessConnectionServer, you have a vector of the InterprocessConnections you created, so you can iterate that vector.
You can use the connectionLost() callback to remove yourself from that list.

1 Like

@ daniel, Aha OK, thanks for that, I forgot the server has an OwnedArray. I’ll try that.

OK It needs a lot more tests, but I think I got it working. Each plug-in can talk to all the others loaded, and when I close the first one, another becomes the server - nice. :grin:

One more question though…
I want to know what to give for port and address values?

Daniel used 1999 & “127.0.0.1” in his post above - but how do I choose one?
The server will fail if it’s already used by someone else. Do I just go for obscure values and hope for the best?

pretty much, yes.
Have a look at a list of known ports to avoid the obvious:

And only above 1024, the ones below need special privileges.

1 Like

Very useful, thanks man.