How to implement a distributed system for a monitoring platform

I'm having trouble implementing the right templates for a working project and I don't want to precede until the correct design strategy is satisfied.

The project is based on the Genesys Computer Telephony Integration (CTI) platform. Basically, using the SDK provided by Genesys, one client subscribes to multiple Genesys (or TServers) services running remotely. The client then registers a whole bunch of directory numbers (DNs) associated with a specific server and waits for call events. When an event occurs, it is captured by the client and stored in the database. A number of other operations are performed, which at this stage does not matter. Most of the data work is handled by the Genesys ProtocolManager object , so a single event handler captures event data for all clients, which in turn is handled by the EventBrokerService... Here's some simple code to illustrate the connection process, single DN registration, and event function:

        EventBrokerService eventBrokerService;

        using (var client = new TServerProtocol(
            new Endpoint(
                new Uri("tcp://tserver01:11234"))))
        {
            client.Open();

            eventBrokerService = BrokerServiceFactory.CreateEventBroker(client);
            eventBrokerService.Activate();
            eventBrokerService.Register(this.OnEvent);

            RequestRegisterAddress requestRegisterAddress = 
                    RequestRegisterAddress.Create("977845873", 
                                                  RegisterMode.ModeMonitor, 
                                                  ControlMode.RegisterDefault, 
                                                  AddressType.DN);
            IMessage response = client.Request(requestRegisterAddress);
        }

      

and then we listen for events (there are many different events):

    private void OnEvent(IMessage response)
    {
        switch (response.Id)
        {
            case EventACK.MessageId:
                //do something
                break;
            case EventLinkConnected.MessageId:
                var ev = response as EventLinkConnected;
                //Insert event into DB and perform some other operations...
                break;
        }
    }

      

The Genesys platform comes with another component called the Genesys Configuration Server. The config server stores all TServer data, including DN information and a whole bunch of other "objects". It's really just a fancy DBMS. The difference is that you can also subscribe to the config server and log CRUD events (i.e. CreateEvent , UpdateEvent , etc.). Without illustrating the code, the concept is the same as above. (i.e. you can register with several different config servers and listen for CRUD events).

For the most part, I've covered the above in detail and so far I'm happy with the implementation. What I am trying to achieve is as follows:

I am trying to implement a distributed system. In a nutshell, the system will have two components. Monitoring and Dispatch Services (they will all be Windows services)

Monitoring service component

  • "Monitoring Service" connects to 1 or more T-servers to monitor call events.
  • The monitoring service will ALSO subscribe to the dispatcher service

Dispatcher Service Component

  • Dispatcher service connects to 1 or more configuration servers and waits for CRUD events.
  • As soon as an event occurs (i.e. a new DN is added on the configuration server), the dispatcher captures the creation event and notifies all subscribers to the monitoring service. Subsequently, the manager will also update the local database, so the DN information is saved for redundancy (in case the manager cannot connect to the configuration server).
  • The monitoring subscriber to which the newly created DN belongs (distinguished by the unique identifiers DBID and TServerID) will accept the DN and register it for listening (similar to the one shown in the first code snippet). A monitoring user who does not have the required connection to the server will naturally lose the received request.
  • The dispatcher can also receive the newly added servers, but this time he will decide which monitoring service he wants to use so that this monitoring service connects to ANOTHER connection. This will be determined by factors such as the number of current sessions running by the monitoring service, or the amount of memory a single service is playing back at a time.

I came up with some basic concepts, and here are some of the code to illustrate what I have done so far:

The communication method I chose is WCF with NetTcpBinding , so for the simple part, I found the interface:

[ServiceContract(Namespace = "urn:Netwatch", 
                 SessionMode = SessionMode.Required, 
                 CallbackContract = typeof(IDisMonServiceCallback))]
public interface IDisMonService
{
    [OperationContract]
    bool Subscribe(string uid);
    [OperationContract(IsOneWay = true)]
    void Unsubscribe(string uid);
}

[ServiceContract(Namespace="urn:Netwatch")]
public interface IDisMonServiceCallback
{
    [OperationContract]
    bool DNRegistered(int tServerId, string dnEntry);
}

      

and on the dispatcher I executed it:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class DisMonService : IDisMonService
{
    private ConcurrentDictionary<string, IDisMonServiceCallback> subscribers = new ConcurrentDictionary<string, IDisMonServiceCallback>();

    public IDisMonServiceCallback this[string uid]
    {
        get
        {
            IDisMonServiceCallback callback;
            if (!subscribers.TryGetValue(uid, out callback))
                return null;
            return callback;
        }
    }

    public List<IDisMonServiceCallback> GetAllServiceCallbacks()
    {
        return new List<IDisMonServiceCallback>(subscribers.Values);
    }

    public bool Subscribe(string uid)
    {
        IDisMonServiceCallback callback = GlobalHelper.Callback<IDisMonServiceCallback>();

        if (!subscribers.ContainsKey(uid))
            if (!subscribers.TryAdd(uid, callback))
                return false;
        return true;
    }

    public void Unsubscribe(string uid)
    {
        IDisMonServiceCallback callback;

        if (subscribers.ContainsKey(uid))
            if (!subscribers.TryRemove(uid, out callback))
                return;
        return;
    }
}

      

From the code above, it is obvious that each subscriber monitoring service has a unique ID, thus retrieving the service callback context (in case I decided to do some other funky operations).

This is where my dilemma begins. In short, my question is as follows:

  • How can I deal with the DisMonService class when trying to pass messages to all callers from the Dispatcher service. those. added a new DN, call the DisMonService class and notify all subscribers.
  • What would be the best template for implementing updates for all subscribers from DisMonServie

At the moment my dummy client is connecting to the dispatcher and it is registering. Moving forward, which is the best way to access the DisMonService class .

I hope I am not confusing anyone with what I am trying to ask. I think I am really trying to find the best way to implement the above system, any suggestions etc. Some code examples and snippets will be really helpful.

This is my first post, so I apologize to anyone if I haven't explained to myself the forum standards.

+3


source to share





All Articles