How to design the parameter if the type of parameter should be an abstract class - asp.net-core-signalr

I'm design a chating App, and it's message has many type , for example : text, image, card, and the card message is very differect than the text message.
I don't want to create easy method to handle each message , because the message will be lose if the client doesn't support that message type(I want it to show "unsupported message type" instead of nothing happened)
What should I do on server side?
public async Task GroupMessage(string groupId, IMessage message) // the IMessage will lose many thing
{
}

The problem is that what's coming from the client isn't anything but some string data. SignalR has to bind that to the type in your handler. Therefore, all you're left with is IMessage, not something like Text or Image.
For this, you have no choice but to have different handlers, one for each type. That is the only way you can bind all the data, and then successfully interact with that data. You cannot use an abstract class or interface, unless you are fine with only having data that exists on that class or interface.

Related

SyncVar without NetworkServer.Spawn

I have a somewhat complex tree of objects that is generated and configured at runtime. Since the information required to do this is available to both the server and the client, I would like to have both sides generate the objects independently and then link the networked parts up for syncing afterwards.
That is to say, I need a way to make SyncVar work for an object that exists on the server and client but was not originally spawned via NetworkServer.Spawn. Is there a way to manually configure NetworkIdentity such that the Unity networking system understands that something is the same object?
I have the ability to uniquely identify these objects across the network myself, I just need a way to communicate that to Unity. NetworkIdentity.netId is readonly, so that's not an option.
If you make all the initialisation done purely by the server and then pushed to the clients you remove the need to sync afterwards. This also would remove the need to deal with duplicate information (which would ultimately be wasted CPU time at client end).
However, if you are wanting to have clients create the data as well, then I would suggest you have them send appropriate messages to the server with their data, the server can then create the objects for them.
Setup message handlers with NetworkServer.RegisterHandler on the server instance for each type of message you need it to handle,
public enum netMessages{
hello = 101,
goodbye = 102,
action = 103,
}
...
NetworkServer.RegisterHandler((short)netMessages.hello, new NetworkMessageDelegate(hdl_hello));
NetworkServer.RegisterHandler((short)netMessages.goodbye, new NetworkMessageDelegate(hdl_goodbye));
...
private void hdl_hello (NetworkMessage msg){
nmgs_hello m = msg.ReadMessage<nmgs_hello>();
...
}
and use the Send method of NetworkClient to send messages to the server.
You will also need to define message classes based on MessageBase for the actual messages.
public class nmsg_hello : MessageBase {
public int x;
public float welcomeness;
}
NOTE: Make sure you don't base any of your network messages off each other, seems to be bug/feature in Unity (at least the last time I tried it) where it doesn't work if your message is derived from anything other than MessageBase as it's immediate ancestor.

What gets send to the server with request factory

I have problem to understand what does Request factory send to server. I have a method
Request<NodeProxy> persist(NodeProxy node)
NodeProxy is an Object from tree like structure (has child nodes and one parent node, all of type NodeProxy). I'v change only one attribute in the node and called persists.
The question now is what gets send to the server?
In the dock here https://developers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory
there is:
"On the client side, RequestFactory keeps track of objects that have been modified and sends only changes to the server, which results in very lightweight network payloads."
In the same dock, in the chapter Entity Relationships, there is also this:
"RequestFactory automatically sends the whole object graph in a single request."
And I'm wondering how should I understand this.
My problem:
My tree structure can get quete big, lets say 50 nodes. The problem is that for update of one attribute the method
public IEntity find(Class<? extends IEntity> clazz, String id)
in the class
public class BaseEntityLocator extends Locator<IEntity, String>
gets called for each object in the graph which is not acceptable.
Thank you in advance.
The problem you're facing is that RequestFactory automatically edit()s proxies when getting properties, and there's a bug when constructing the request payload that makes the whole graph of proxies to be implicitly edited that way, even if you didn't call the getter yourself.
That bug has many repercussions, including false-positives in RequestContext's isChanged(): http://code.google.com/p/google-web-toolkit/issues/detail?id=5952
I have great hopes that this will be fixed in GWT 2.5 (due in the next weeks).

msmq multiple message types in a single queue

I'm planning on having a single queue receive ~100 different message types.
If I had only had 2 different types I'd do something like this
MessageQueue queue = new MessageQueue(_queue);
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(CreateReportComand), typeof(CreateReportComand2)});
Is it craziness to pass XmlMessageFormatter an array of ~100 Types. And if not what is the best way to examine the received message to decide how to handle it?
You can use the WCF MsmqIntegrationBinding and handle messages of type MsmqMessage<string>. Then your handler method will receive the serialized message as a string and can do what you want with it after that.
I preffer not to use Message.Formatter and Message.Body. Instead I use Message.BodyStream manualy serializing/deserializing my messages.
Type of the message can be embeded in serialized data (that is what I do) or you can put it on message header or on label.

Using different delegates for NSXmlParser

I am trying to figure out the best way to design something. I am writing an iPhone App and for the most part I am using async calls to a web service. This means that I cam setting up a URLConnection, calling start and letting it call me back when the data is available or an exception occurs. This works well and I think is the correct way to handle things.
For example:
I request a list of people from a web service. The resulting list is Xml Person elements which will be translated into an objective-c "Person" object by my XmlDelegate.
When I call the function to get the person, I pass in a "PersonResultDelegate", which is a protocol with a single function called "PersonReceived:(Person *)p". So, each time I get a complete Person object, I call that method and all is well. So, my detail view (or search result view) just receives the elements as they are available.
The problem comes when I need to obtain more then one specific object. In my specific case, I need to get the first and last appointment for a person. So, I need to make two API calls to obtain these two single Appointment objects. Each Appointment object will result in a call to the registered AppointmentResultDelegate, but how will I know which is the first and which is the last? I also need to somehow handle the case when there is no "first" or "last" Appointments and the Delegate will never get called.
What would be the correct way design wise to handle this? Should I add some additional context information to the initial request which is passed back to the handle in the delegate? An opaque piece of data which only makes sense to the person who made the initial call? What are my other options?
Solution
What I actually ended up doing is just passing an opaque piece of data along with the Appointment to the delegate. So, when I request an appointment object I have a method like:
getNextAppointment withDelegate:self withContext:#"next"
getPrevAppointment withDelegate:self withContext:#"prev"
This way when the delegate gets called I know what appointment is being delivered.
"Each Appointment object will result in a call to the registered AppointmentResultDelegate, but how will I know which is the first and which is the last?"
By looking at the order in which you receive these callbacks. Or by looking at some value in that xml data. Like a sequence or data. I don't know your data of course.

Custom activity based on HandleExternalEventActivity

I'm using HandleExternalEventActivity with Roles property and I need to check if my custom bool RoleProfile.IsDelegatee(string userName, string workflowName, string activityName, string eventName, string roleName) method finds a match. ("I'm on vacation; UserX should be able to approve 'task X' on my behalf, but not 'task Y'")
I tried to inherit HandleExternalEventActivity but Execute method was marked as sealed.
Do you have any ideas?
TIA
I don't think the HandleExternalEventActivity lets you do this, it's limited in what it will let you validate. However the ReceiveActivity has a OperationValidation event that lets you do whatever you want in code and set an IsValid property on the OperationValidationEventArgs to indicate if the call is allowed or not.
If you are not willing or able to go the WCF route the best option is to create a custom activity that reacts to queued messages. The HandleExternalEventActivity is only a very thin wrapper over the workflow queuing system and I nearly always advise people to go the custom activity route instead of the HandleExternalEventActivity route as it is far more flexible and often even easier to use.