systemd tends to work slightly differently. You configure systemd to create and listen on the socket, and should anyone like X try to connect, then systemd launches Y to handle the connection, passing it the socket. So X can start notionally before Y, but it will not matter. Later connections will be handled by Y. (You can also configure it so Y is restarted for each connection, but I presume that is not your case).
The minimal changes to Y are to have it accept the pre-created socket as its stdin/stdout file descriptor, instead of doing the create/bind itself.
Here's a test setup you can try, not as root. You need 3 unit files.
~/.local/share/systemd/user/mysock.socket tells systemd to create the socket and how to pass it on:
# create listening socket. on 1st connect run mysock.service
~/.local/share/systemd/user/mysock.service (having the same name
mysock) is the service that will be started should anyone connect to the socket. This is where you start Y, which I have replaced by some python.
Description=started from mysock.socket
Finally, your X service has a Unit saying it requires the socket. For X I am using a socat that writes the date to the socket.
Description=dependent on socket listening
ExecStart=/usr/bin/socat -U tcp:localhost:5555 exec:/usr/bin/date
The python takes the socket on stdin, i.e. file descriptor 0, and wraps it into a suitable python socket object, does an
accept() and can read/write to it:
# started from /home/meuh/.local/share/systemd/user/mysock.service
# with socket on stdin/stdout
import sys, time, socket, subprocess
s = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
conn, addr = s.accept()
data = conn.recv(100)
if len(data)<=0: break
systemctl --user daemon-reload,
you should be able to run X with
systemctl --user start mysockdepend
and see in the logs with
journalctl that Y was started, and the debug output with the date.
Read about socket activation and 2nd from the man who invented it.