| |
| Posted by Hossain Adnan in reply to Hossain Adnan | PermalinkReply |
|
Hossain Adnan
Posted in reply to Hossain Adnan
| On Thursday, 10 October 2019 at 12:30:25 UTC, Hossain Adnan wrote:
> Here I have a program that wants to
>
> 1. detect whether if it's the only instance
> 1.1. it does that by trying to create a Unix Domain Socket
> and trying to binding it to a specific address.
>
> 2. if a duplicate program is not running, establish an UDS
> and then listen to the socket.
>
> 2.1. if any message comes through that socket, the program will log the incoming message
> 2.2. otherwise it should keep listening to the socket forever
>
> 3. if there's a duplicate program it should send a message and then exit.
>
> Here's what I have:
>
> import std.socket, std.experimental.logger;
>
> immutable string socketAddress = "\0/tmp/com.localserver.myapp";
>
> void main()
> {
> auto socket = new std.socket.Socket(std.socket.AddressFamily.UNIX,
> std.socket.SocketType.STREAM);
> auto addr = new std.socket.UnixAddress(socketAddress);
>
> auto isUnique = () {
> bool result;
>
> scope (success)
> log("returns: ", result);
>
> try
> {
> socket.bind(addr);
> result = true;
> }
> catch (std.socket.SocketOSException e)
> result = false;
>
> // else throw error
> return result;
> }();
>
> if (isUnique)
> {
> log("Unique instance detected. Listening...");
> // works upto now
> char[] buffer = [];
> while (1)
> {
> socket.listen(0);
> socket.receive(buffer);
> if (buffer != []) {
> log("Received message: ", buffer);
> }
> buffer = [];
> }
> }
> else
> {
> log("Duplicate instance detected.");
> socket.connect(addr);
> import std.stdio;
> stdout.write("Enter your message:\t");
> socket.send(readln());
> log("Message has been sent. Exiting.");
> }
> }
>
>
> The documentation does not seem very friendly to those who does not have any experience in socket programming.
Consulted stackoverflow and came up with this:
import std.socket, std.experimental.logger;
class UDSIPC
{
private:
static immutable string socketAddress = "\0/tmp/com.localserver.myapp";
static immutable size_t messageBufferSize = 64;
static immutable string socketAddressName = "\0/tmp/com.localserver.myapp";
Socket socket;
UnixAddress uaddr;
public:
this(in string socketAddressName = socketAddressName)
{
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
uaddr = new UnixAddress(socketAddress);
}
bool getUniqueness()
{
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(uaddr);
result = true;
}
catch (SocketOSException e)
result = false;
// else throw error
return result;
}
string getMessage()
{
socket.listen(0);
auto receiverSocket = socket.accept();
char[messageBufferSize] buffer;
auto amount = receiverSocket.receive(buffer);
import std.string;
return format!"%s"(buffer[0 .. amount]);
}
void sendMessage(in string message)
{
socket.connect(uaddr);
socket.send(message);
}
}
void main()
{
auto ipc = new UDSIPC();
if (ipc.getUniqueness())
{
while (true)
{
log(ipc.getMessage());
}
}
else
{
import std.stdio, std.string;
ipc.sendMessage(readln().chomp());
}
}
|