Client/Server communication with Named Pipes
Most relevant code: https://gist.github.com/just-ero/a9bb60192a7cc090cb9055dc39770139
Context: I'm reading some information from Mono-based processes (mainly Unity games). For this, I use injection to call the Mono API. I have a client sending request codes and payloads to the server in the injected DLL, which sends response payloads.
Unfortunately, I feel like I've made quite some missteps in designing this process. For example:
- I cannot send a "failure" response; I simply send a response payload with default values,
- I cannot log,
- Request codes are not tightly coupled with their respective request payloads,
- When the client side does not shut down gracefully, the server side does not shut down (because
IsConnected
is never set to false
),
- The server library has to implement the loop for listening manually, I'd like that to be part of the server class itself.
In general, I feel like I went a bit too far with the amount of inheritance I use for the servers. I abstracted the servers so much that I only return payloads instead of result-type values (even though I do have a Result
type).
I would like some help in making this whole system more robust and more intuitive to use and expand upon. I would like a way to add logging (ideally in the form [ServerName] [Method] Actual Log
). I would like to shut down (or halt) the server when the client does not shut down gracefully. And I would like someone to look over my ApiSerializer
class to spot anything that can be written better. The entire way I exchange data feels very opaque and convoluted (I even get confused myself).
I'm on .NET Standard 2.0 for all of this, so a lot of features simply aren't available to me.9 Replies
is this the project with thousands of classes?
What?
I don't think I have a single project like that
maybe it was someone else
how do you want the logging to work, should the server send a log message to the client and the client writes it to file?
i was going to use simply
Debug.WriteLine
, a file would be fine too.what do you mean by "Request codes are not tightly coupled with their respective request payloads"
do you reuse some classes for more requests/responses?
this was actually wrong, you can see in the gist that
IRequest
defines RequestCode Code
which is... not the best solution (it means i'm sending first the request code, and then the payload which contains the request code again)
i need to send the code separately, of course, so the server knows what type of payload to read nextif this was a binary serializer i could understand it
but you are sending json, and (reasonably) you send the length of the packet
you could have type as a field of the model, either string or number
well, like i mentioned, the type is currently part of the model.
but that isn't really helpful, since i need to send the type first, and separately, anyway. otherwise, the server wouldn't know what model to read next.
in the sense that
code
is a hint, yes, but if possible (and it should be) i would prefer an automatically managed discriminator
field/polymorphism
and/or also you should be able to deserialize the json using the raw deserializer, get the type field, and use the specific method to cast to a type
although i have not benchmarked that and don't know how performant it is
so to be clear you would want an independent channel/multiplexing of messages for the logs
like building an event bus
first time i say this but probably wouldn't hurt to discuss in voice chat