Serial communication design pattern - c#

I'm currently assigned to a task to develop a software module to communicate with a stepper motor controller. The project is written in C#, I have a C++ dll to communicate with the controller. The communication runs via the Serial port. I'm planning to write the whole piece in C# by importing the necessary methods by DllImport. The key method looks something like :
ComSendReceive(pHandle, bufferIn,sizeBufferIn,bufferOut,ref bufferOut)
There are several types of messages :
You send message and expect confirmation (not the same for every message, sometimes it's OK, sometimes it's COMPLETE etc..
You send message and receive message - you can receive an error or data (for instance GET_CONTROLLER_ID)
Several other types
Of course I need to control the communication for time-outs.
My question is: Is there any "design pattern" to use for that kind of problem? I'm sure this is quite a common problem many developers have solved already.
To contribute a little - I dealt with similar problem in my last job and I solved it this way :
I had a class to communicate with the Com port and a class AT_message with bunch of overloaded constructors :
class AT_Message
{
public bool DoResponseCheck;
public string ExpectedResponse;
public AT_COMMAND command;
public string data;
public bool AddCarriageReturn;
...
//Plenty of ctors
}
class UnfriendlyInterface
{
Response SendMessage(AT_Message msg)
{
//Communicates directly with C++ dll, send message, check timeouts etc....
}
}
And I had a class the main application was communicating with, it had human friendly methods like
class FriendlyInterface
{
bool AutodetectPortAndOpenComm();
Result AnalyzeSignal(byte[] buffer)
{
Response response = UnfriendlyInterface.SendMessage(new Message(AT_Command.PrepareForSignal, (doResponseCheck)true, ExpectedResponse.Ok,Timeout.short);
Response response = UnfriendlyInterface.SendMessage(new Message(buffer,(doResponseCheck)false,Timeout.long);
//.... Other steps
}
//... other methods
}
Since last time I was really in a big hurry, I implemented first solution that came to my mind. But is there a way to do it better? Now the device I'm communicate with is more complex than the previous one so if there's a way how to do it better, I'd like to do it that way.

This seems like a textbook facade pattern. The answer to all of this is to encapsulate your variation. For example, try to create a generic interface for commands that give an acknowledgement, and write client code to use that interface. Then concrete types can decide how to interpret various acknowledgements into a uniform signal (Ok = Complete = Good, or whatever)
Here's a good article on the facade pattern. Also see the wikipedia article.

Related

Using C# Attributes, how would I trigger functions to be executed on change of their assigned field

I am currently developing a network Library for Unity as the one integrated is not quite what our game needs.
Several things such as too much abstraction and many limitations forced us come up with our own solution.
The whole communication happens on top of standard .Net Sockets.
The system we developed is mostly built using internal classes and structures that don't really need to be explained any further.
The important thing is our ShatNetTransportLayer class.
It's a static class that internally uses two buffers, one for the receiving of data, one for the transmitting.
Another higher level class works pretty much like a "network gc".
Messages get pushed onto a send list, which is regularly being checked and freed, once all messages have been send. This is of course simplified, actually there are ack checks for different channels etc.
So far to the setup.
The important thing I need to know is as follows.
Each Object in the game that is to be networked will hold a ShatNetIdentity.
This is the core class that registers networked objects on the server and keeps them sycned on each client side.
While this isn't fully implemented yet, we have another problem to overcome.
The plan is that each ShatNetIdentitywill be the core component of a networked gameobject, so that any ShatNetBehaviour can access it via the gameobject.
ShatNetBehaviour is a class derived from monobehaviour which is Unity's default class to deal with in scene elements.
The only thing it adds on top of it is the possibility to get the ShatNetIdentity associated with the object the script is attached to.
Now comes the crucial part:
Since we have devs in our team that never barely touched a networking system, we need to abstract the syncing of variables, probably even the remote method calls.
Internally all that will be sent is the message with a max size of 128Byte.
Part of that is the MessageType, a 1Byte long unsigned int that represents the type of the message, like Variable syncs, message calls, disconnected players and that stuff.
Second is the sender ID represented by 2Byte.
Rest is the message itself.
There is more involved but that's the core.
This is still to be fully determined, but you get the idea.
These messages are written to the buffer and send when a send is scheduled or received when receive event occured.
Back when we used Unity's own UNet, you could just add an attribute called SyncVar to any field of a class which is part of an object that has a ShatNetIdentity attached.
There was also a way to define a callback function if the value changed.
Reference: https://docs.unity3d.com/ScriptReference/Networking.SyncVarAttribute.html
Example:
//When this is not our client, this value will be updated automatically across the net
[SyncVar(hook="OnHealthChanged")]
int health;
void OnHealthChanged()
{
doStuff();
}
So my question is, is there any way to implement this ourselves?
The names we had in mind are NetVar and NetHook.
To have a variable synced accross the network one would simply write
[NetVar]
private int health;
void TakeDamage(int amount)
{
//Updates health for all clients
health-=amount;
}
To make this happen, several things would happen.
When a new ShatNetIdentity is spawned, register it on the server.
Register every variable of each class that is attached to a gameobject with
ShatNetIdentity on that identity.
Probably not possible that way, because access levels? Use public properties inside of the attribute ?
When receive buffer is populated check messages for variable update types, find the index of the ShatNetIdentity and the referenced variable.
Update that variable on each client
So things I'd need to get a hint for would be
how do I reference private variables on a ShatNetIdentity(Could be any class of course). Supported types are base types, nothing else, but there must be one attribute that covers them all. Nothing like NetBool, NetInt...
How do I reference callback functions with an attribute and trigger them when the value of the field is changed.
What other options could I use.
Ideas that I had so far:
Create networked basetypes for every base type.
This would look ugly and wouldn't really help maintining easy code.
I hope I explained everything well enough. If any detail needed, just shoot.
Thanks a lot for your help.
Edit:
Looks like SynVar is just a tag for code to be generated.
http://blogs.unity3d.com/2014/05/29/unet-syncvar
How can this be done?
I believe, for your case, you could go one of two routes. A broadcast style system, or a registration style system.
In a Broadcast scenario, your communications component (class), could declare something like:
public event Action<(string shatNetIdentity, MessageType messageType, string message)> Message;
And then invoke when a message is correctly received:
Message?.Invoke((id, messageType, message));
The receiving object would then have to determine if the message was intended for it, and if so, what type of message it actually was and how to deal with it.
In a Register scenario, your objects could register to the communications component. You could have a Dictionary in your comms component:
private Dicitionary<string, INetworkObject> Registrations;
public void Register(INetworkObject o)
{
Registrations[o.ShatNetIdentity] = o;
}
private void ReceiveMessage()
{
// receive and parse message.
if ( Registrations.TryGet(message.Id, out INetworkObject o )
{
switch (message.messageType)
{
case MessageType.Health:
o.Health = message.Health;
break;
// etc..
}
}
}
Where INetworkObject is something like:
public interface INetworkObject
{
string ShatNetIdentity {get; set;}
float Health { get; set; }
Vector3 Position {get; set;}
}
There's obviously no error checking here. And if it were me, I'd probably go with the second scenario. The first scenario might be easier to implement if there were only a few objects listening to the event, but isn't optimal if there are many objects, as the event is broadcast to every object listening.

How to use Caliburn Micro's EventAggregator to send empty events (no payload)?

I found articles about and solutions to this question pertaining to Prism, but I didn't find anything pertaining to Caliburn Micro. I checked all questions here tagged with Caliburn.Micro and EventAggregator, but didn't find anything Caliburn specific about this seemingly basic issue.
Scenario: I want to publish events to the EventAggregator that don't have any information, other than signaling that something happened.
Problem: First, in Caliburn Micro, the EventAggregator's Publish() method requires an instance of a type to be sent. Second, subscribing and handling events require the implementation of the IHandle<T> interface, where T is the type of instances that we want to receive. It seems that this is fully designed around publishing and handling actual data.
Goal: To be able to publish simple events without having to create and instantiate multiple empty/dummy classes, and without having to Handle() unnecessary events that I need to filter further with conditionals.
My solution so far
This is what I want to improve/replace. (Obviously, this solution is problematic because it creates tighter coupling around the concrete classes, but in my use case this is not a big issue, since it's a small project with singular publishing components for a given event, and the EventAggregator serves other practical goals.)
I made a generic Signal<T> class that implements the singleton pattern, providing a static instance of itself through the Instance property:
public class Signal<T>
{
public static readonly Signal<T> Instance = new Signal<T>();
private Signal() { }
}
So I can publish events in the following way (SignalSourceClass is an example):
_eventAggregator.PublishOnUIThread(Signal<SignalSourceClass>.Instance);
And handle events by declaring the implementation of IHandle<T> in the following way:
IHandle<Signal<SignalSourceClass>>
This way I can send and receive "empty" events by creating only this single Signal class. (Of course this is a limited solution, since components can only send one event this way.)
I suspect that this solution is primitive (well, let's just call it a fact), and that there is something better that I'm overlooking.
Just create a enum with all possible signals you want:
public enum ProjectSignals
{
Connected,
Disconnected,
Openned
}
then just
_eventAggregator.PublishOnUIThread( ProjectSignals.Connected );
and
class SomeClass : IHandle<ProjectSignals>
{
public void Handle( ProjectSignals signal )
{
switch (signal)
{
case Connected:
break;
}
}
}

Central Message Manager for managing different messages between different classes

I am writing an application in C#. Now i am thinking over and over again about its design. Have already changed my mind 3 or 4 times but thankfully for the good.
After few iterations i come up with a solution but i am still wondering what is the best way to achieve that with C#.
Basically i will have a class lets call it MessageManager, and after each action different classes will send a message to MessageManager and MessageManager will send the message depending on the response. Then i will have another manager call it UIManager it will perform all the UI switching or inform the MessageManager in case of any core/helper operation is required.
Now the thing is messages could make up to like 50-60 types each will have different type of arguments. And i want to design it in a way if i have new messages in future it can accommodate that as well.
What is the best way to accomplish that in C# like what will be the best for such case delegates, events. Flexibility is the most important thing.
I believe that combining the Observer pattern (publish/subscribe logic) along side with the Mediator one can be a good solution to your problem. Your Mediator class will act as an Event Manager (most of your classes will depend on it as a mediator rather than depending on each others) :
public class MessageManager{
private Dictionary<string,List<MessageListener>> listeners;
public void sendMessage(Message m){
//loop over listeners of m
}
public void addMessageListener(MessageListener ml){
//add a listener
}
public void removeMessageListener(MessageListener ml){
//remove a listener
}
}
Message would be the parent interface, having a generic abstraction at this level is very important as it avoids the MessageManager from distinguishing between your 50-60 types of messages and thus becoming a nightmare to maintain. The specificity of depending on a particular sub-type of Message should be moved to a lower level: the direct consumers.

Need advice on how to design this. Composition or inheritance?

I'm trying to design a client / server solution. Currently it contains three projects. The client, the server, and a library that each use (because they both require a lot of the same stuff).
For example, both the client and the server (in this case) read incoming data in the exact same way. Because of this, both the client and the server have their own MessageReader object. The MessageReader will first read the first 4 bytes of incoming stream data to determine the length of the data and then read the rest. This is all performed asynchronously. When all the data is read the class raises its own MessageRead event or if there was an IOException while reading it raises its own ConnectionLost event.
So this all works fine. What's the problem? Well, the client and the server are a bit different. For example, while they may read data in the same way, they do not write data in the same way. The server has a Dictionary of clients and has a Broadcast method to write to all clients. The client only has a single TcpClient and can only Write to the server. Currently all this behavior is within each respective WinForm and I want to move it to a Client and Server class but I'm having some problems.
For example, remember earlier when I was talking about the MessageReader and how it can raise both a MessageRead event and a ConnectionLost event? Well, now there's a bit of a problem because in designing the Client class I have to capture these two events and re-raise them because the client form should not have access to the MessageReader class. It's a bit ugly and looks like this:
class Client
{
private MessageReader messageReader = new MessageReader();
public delegate void MessageReceivedHandler(string message);
public delegate void ConnectionLostHandler(string message);
public event ConnectionLostHandler ConnectionLost;
public event MessageReceivedHandler MessageReceived;
public Client()
{
messageReader.ConnectionLost += messageReader_ConnectionLost;
messageReader.MessageReceived += messageReader_MessageReceived;
}
private void messageReader_MessageReceived(string message)
{
if (ConnectionLost != null)
{
ConnectionLost(message);
}
}
private void messageReader_ConnectionLost(string message)
{
if (MessageReceived != null)
{
MessageReceived(message);
}
}
}
This code is ugly because its basically duplicate code. When the MessageReader raises the MessageReceieved handler the Client has to capture it and basically re-raise its own version (duplicate code) because the client form should not have access to the message reader.
Not really of a good way to solve it. I suppose both Client and Server could derive from an abstract DataReader but I don't think a client is a data reader, nor is the server. I feel like composition makes more logical sense but I can't figure out a way to do this without a lot of code duplication and confusing event handlers.
Ouch, this question is getting a bit long.. I hope I don't scare anyone away with the length. It's probably a simple question but I'm not really sure what to do.
Thanks for reading.
Composition.
I didn't even read your code or text. I find that the average developer (almost) never needs inheritance but they like to use it quite a bit.
Inheritance is fragile. Inheritance is hard to get correct. It's harder to keep it in check with SOLID.
Composition is easy to understand, easy to change, and easy to DI, Mock, and test.
SOLID
I ended up using inheritance for this even though the relationship wasn't strong. The code duplication it got rid of was worth it. Was able to place all the events both classes shared in to the base class.

collecting statistics via callback method

I'm tring to pass "statistics" from one program to another (my first question is here how to pass some "statistics" from c# program to another program?)
To pass statistics I first need to collect it.
I've decided to implement central storage, like StatisticsStorage with one method StatisticsStorage.joinStatistics(string groupName, string indicatorName, callback getValueMethod)
Then for example Thermometer class should look like that (pseudo code):
class Thermometer {
Thermometer(string installationPlace) {
StatisticsStorage.joinStatistics("temperature", installationPlace, this.getThermometerValue);
}
callback double getThermometerValue {
return this.thermometerValue;
}
private double thermometerValue;
//.....
}
StatisticsStorage should call callBack method for all indicators periodically.
Once statistics is collected I can pass it one way or another.
Questions:
do you see any problems with my approach?
how to implement callbacks on c# better? (i'm pretty novice to c#)
There are probably many ways to achieve your desire result.
I would probably publish a WCF service, maybe hosted in a windows service, and you can connect and post stats on that. This will keep a good separation of system concerns and can be reused from other systems etc etc.
I suppose it depends on how in depth you want to go and the requirements in this scenario.
Then again, i could just be over analyzing what you are trying to do :)

Categories

Resources