Proper Path for IPCSocket

Hey all,

I’m having a problem with a Windows customer and an IPCSocket path. My socket path is this:

MyIPCSocket.Path = SpecialFolder.Temporary.Child("MediaSwitcher.socket").NativePath

For the customer in question, this path is:

C:\\Users\\Mini PC\\AppData\\Local\\Temp\\MediaSwitcher.socket

When trying to connect the IPCSocket, I am getting a 103 error. That is a name resolution error.

I’m not entirely sure why I am getting that error. Seems like the socket is not able to find that path. I don’t get any path errors as I am checking for them:

If SpecialFolder.Temporary.Child("mediaswitchersocket") = Nil Or SpecialFolder.Temporary.Child("mediaswitchersocket").LastErrorCode <> 0 Then
  System.DebugLog "IPCSocket file not available."
  System.DebugLog "IPCSocket Error Code is : "+ Str(SpecialFolder.Temporary.Child("mediaswitchersocket").LastErrorCode)
End If

And I don’t see any of those entries in the debug log.

Ideas? Do I need to use a different path type?

OK. I changed the code (fixed above) and I am not getting any NIL or FolderItem errors. So anyone know why I might be getting an error code of 103?

Thanks!

so you’ve made the two paths match then ? as they dont in the code above
they are different case and that can be relevant

MyIPCSocket.Path = SpecialFolder.Temporary.Child("MediaSwitcher.socket").NativePath

If SpecialFolder.Temporary.Child("mediaswitchersocket") = Nil Or

I’d expect the space in the path would be something other users also have ? maybe not ?

Yes. I missed that in the edit on the forum. I’m not really concerned about the IF/Then statement for the error checking. Here is the correct code:

MyIPCSocket.Path = SpecialFolder.Temporary.Child("MediaSwitcher.socket").NativePath

System.DebugLog "IPCSocket Path is :"+MyIPCSocket.Path

If SpecialFolder.Temporary.Child("MediaSwitcher.socket") = Nil Or SpecialFolder.Temporary.Child("MediaSwitcher.socket").LastErrorCode <> 0 Then
  System.DebugLog "IPCSocket file not available."
  System.DebugLog "IPCSocket Error Code is : "+ Str(SpecialFolder.Temporary.Child("MediaSwitcher.socket").LastErrorCode)
End If

I don’t know about other users. All I am trying to do is connect to the IPCSocket. I do see in the debug logs that it does appear to initially connect. After that every write or attempt to access the socket results in the 103 error.

But it’s never going into the If/Then branch.

Try to not use the TemporaryFolder, but, fir testings, the Documents folder (for example).

If it works…

[quote=449781:@Jon Ogden]
I don’t know about other users[/quote]
I meant other users of your software
Surely this cant be the only one that has a path that has a space in it ?

In a projectnot related to IPCSocket, I was not able to delete a file from the TemporaryFolder (and that file was there, on macOS, cause at reboot time, it was there !). I do not checked the error #.

But Windows doesn’t use the file. No file is ever created if you look in the path. It’s because Windows uses a network socket. I remember reading that…

should be using a TCP socket bound to the local loopback port

Is this the recommended way to do it instead of using an IPCSocket? Why should I not be able to use Xojo’s built in class?

that IS what an IPCSocket on windows already is … sorry for the lack of clarity

OK. So yeah, it should. I wonder if it’s a firewall issue? Something is causing a Name Resolution Error.

Could be a firewall blocking it but connecting to the local loopback I thought wasnt supposed to cause that
Possibly multiple firewalls with different settings ? (Windows + some antivrus one ?)

You can use whatever you like for path, including a random string. The Windows implementation just translate the string into a port with a known algorithm.
I use it with UUID for example.

Based on this conversation http://forums.realsoftware.com/viewtopic.php?p=15645 I gave up on using IPC Sockets and use server sockets. This allows me to reject connections from other than 127.0.0.1 (if required) and still be listening and also gives me the ability to communicate with multiple helpers/clients.

I implemented IPC sockets in a system which uses lot of sockets in a multi user environment and I can say after some initial problems it now works very well and reliably. This is on both Mac and Windows, due we have cross platform system.
The only problem I found on Windows is that, being this tied to a TCP port you need to consider on opening a new socket if that port is already taken. It would be nice to be able to feed the IPCSocket with the real TCP port to open instead of a string for which you can’t predict on which port will be translated.

OK all, I think I figured out the problem and I am not sure if this is new to 2019R1 or not because I haven’t seen this before. It’s not a Windows problem as I’ve duplicated this on the Mac. Here’s what I do…

I have two apps. I want those apps to communicate with each other when both are running. The problem is I don’t know which app the user started first. I need the first app to be a listener. So when the app starts, it attempt to listen on the IPCSocket. If that works, great. If the app being started is the second app, then when I call ICPSocket.Listen, I get an error 105. Then in the error handler, I have code to reset the socket and call Connect.

The problem I am seeing is that once this now happens, the socket is FUBAR period. You always end up getting a 103 error whenever you try to connect. It doesn’t matter if you quit and restart the app. It’s FUBAR.

I’ve duplicated this many times using the example applications. I start one of the example apps and click the listen button. I then start the second copy of the example app and click listen. I get an error 105. I then quit that copy. I restart that copy and click connect. I get error 103. I then quit the second app again and try it again - I still get 103. Nothing has thrown an error in the first app so I don’t know that I need to reset that socket or do anything. But the socket is completely hosed. Nothing can connect to it now.

I’ve been using the IPC this way for several years and I have never seen this behavior until now…

Anyone have any ideas???

I believe I have developed a workaround for this. Instead of calling Listen first, I check to see if there’s a Mutex that I can enter. If I can, then I know I am the first app running and can call Listen. The second app comes on and checks to see if It can enter the Mutex and can’t, so it connects.

When the socket disconnects, I attempt to leave the Mutex, etc.

So far it seems to work…

Another technique that’s useful: if app A is launching app B, then app A can pass in the IPCSocket’s path to let the other app know what it is (this can be done on the command line, or using environment variables…). This only works if one app is launching the other, though.

If only it were that easy! In this case they are two independent apps. One is a desktop version and one is a standalone web app. I want to be able to sync data between them when both are running (it’s a video control system) so that when a user makes a change on one platform, it’s updated on all the others. The problem is I just never know which is running in the first place.

My long term goal is going to be to completely decouple both the desktop UI and the Web UI from the backend operations of the app. I’ve started this (and it should have been done this way from the get-go but 9 years ago I was just learning RealBasic) but it will take a while to finish. Once I get that decoupling done, the web app engine will do all the heavy lifting and run as a service in the background. The desktop app will then use IPC exclusively to send commands to the web app and get data back. Then I don’t have to worry about this because I’ll always set the Web app service to listen on IPC.