How to handle incoming commands using event arrays?

I am currently working on a simple Client / Server model that sends packets in TCP packets (e.g. HTTP), and the commands are mostly ints (the first 4 bytes of each packet), and I would like to develop an efficient way to handle these commands.

The most obvious answer would be to write thousands if or make one huge switch statement with thousands of cases, but isn’t the best way?

I would like to create an array of events and then just raise the corresponding index so that each int refers to a single event that is called (e.g. MessageReceived). I would also save time, I think, so how can I fix this?

EDIT: the server handles several connections, one for each connected client, so creating separate connections for each command is not so useful in my case.

+4
source share
2 answers

Sounds like a job for listings!

enum YourEnum { DoThis, DoThat } YourEnum foo = (YourEnum)yourInt; 

Visual studio can even create an entire switch statement using inline snippets, and your code will become very readable.

 switch(foo) 

becomes

 switch(foo) { case YourEnum.DoThis: break; case YourEnum.DoThat: break; default: break; } 

Update 1

It's a little scary in terms of maintainability, but if you created a class like:

 public class ActionProcessor { public void Process(int yourInt) { var methods = this.GetType().GetMethods(); if (methods.Length > yourInt) { methods[yourInt].Invoke(this, null); } } public DoThis() { } public DoThat() { } 

or a little nicer, but harder to maintain:

 [AttributeUsageAttribute(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] public sealed class AutoActionAttribute : Attribute { public AutoActionAttibute(int methodID) { this.MethodID = methodID; } public int MethodID { get; set; } } public class ActionProcessor { public void Process(int yourInt) { var method = this.GetType().GetMethods() .Where(x => x.GetCustomAttribute(typeof(AutoActionAttribute), false) != null && x.GetCustomAttribute(typeof(AutoActionAttribute), false).MethodID == yourInt) .FirstOrDefault(); if (method != null) { method.Invoke(this, null); } } [AutoAction(1)] public DoThis() { } [AutoAction(2)] public DoThat() { } } 

Update 2 (The coding I'm thinking of, says Josh K.)

 // Handles all incoming requests. public class GenericProcessor { public delegate void ActionEventHandler(object sender, ActionEventArgs e); public event ActionEventHandler ActionEvent; public ProcessAction(int actionValue) { if (this.ActionEvent != null) { this.ActionEvent(this, new ActionEventArgs(actionValue)); } } } // Definition of values for request // Extend as needed public class ActionEventArgs : EventArgs { public ActionEventArgs(int actionValue) { this.ActionValue = actionValue; } public virtual int ActionValue { get; private set; } } 

This creates SomeActionProcessor, which is responsible for some value:

 // Handles a specific (or multiple) requests public class SomeActionProcessor { public void HandleActionEvent(object sender, ActionEventArgs e) { if (e.ActionValue == 1) { this.HandleAction(); } } private void HandleAction() { } } 

Then create classes and connect them:

 GenericProcessor gp = new GenericProcessor(); SomeActionProcessor sap = new SomeActionProcessor(); gp.ActionEvent += sap.HandleActionEvent; 

Burns and sends general processor requests:

 gp.ProcessAction(1); 
+3
source

Perhaps you can use the subscriber-subscriber model. Instead of having one listener, you will have a lot. Each listener will listen to at least one command. Then you can split your switch into several classes.

+1
source

Source: https://habr.com/ru/post/1438516/


All Articles