void IUniversalDuplexContract.SendToService(DuplexMessage msg)
        {
            //We get here when we receive a message from a client

            IUniversalDuplexCallbackContract ch = OperationContext.Current.GetCallbackChannel <IUniversalDuplexCallbackContract>();
            string session = OperationContext.Current.Channel.SessionId;

            //Any message from a client we haven't seen before causes the new client to be added to our list
            //(Basically, treated as a "Connect" message)
            lock (syncRoot)
            {
                if (!clients.ContainsKey(session))
                {
                    clients.Add(session, ch);
                    OperationContext.Current.Channel.Closing += new EventHandler(Channel_Closing);
                    OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
                    OnConnected(session);
                }
            }

            //If it's a Disconnect message, treat as disconnection
            if (msg is DisconnectMessage)
            {
                ClientDisconnected(session);
            }
            //Otherwise, if it's a payload-carrying message (and not just a simple "Connect"), process it
            else if (!(msg is ConnectMessage))
            {
                OnMessage(session, msg);
            }
        }
        /// <summary>
        /// Pushes a message to one specific client
        /// </summary>
        /// <param name="clientSessionId">Session ID of the client that should receive the message</param>
        /// <param name="message">The message to push</param>
        protected void PushMessageToClient(string clientSessionId, DuplexMessage message)
        {
            if (clients != null && clients.ContainsKey(clientSessionId))
            {
                IUniversalDuplexCallbackContract ch = clients[clientSessionId];

                IAsyncResult iar = ch.BeginSendToClient(message, new AsyncCallback(OnPushMessageComplete), new PushMessageState(ch, clientSessionId));
                if (iar.CompletedSynchronously)
                {
                    CompletePushMessage(iar);
                }
            }
        }
        public void CompletePushMessage(IAsyncResult iar)
        {
            IUniversalDuplexCallbackContract ch = ((PushMessageState)(iar.AsyncState)).ch;

            try
            {
                ch.EndSendToClient(iar);
            }
            catch (Exception ex)
            {
                //Any error while pushing out a message to a client
                //will be treated as if that client has disconnected
                System.Diagnostics.Debug.WriteLine(ex);
                ClientDisconnected(((PushMessageState)(iar.AsyncState)).sessionId);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Pushes a message to one specific client
        /// </summary>
        /// <param name="clientSessionId">Session ID of the client that should receive the message</param>
        /// <param name="message">The message to push</param>
        protected void PushMessageToClient(string clientSessionId, DuplexMessage message)
        {
            try         //try to send message to client if it is still connected. Otherwise dont worry about it.
            {
                IUniversalDuplexCallbackContract ch = (clients[clientSessionId]).Channel;

                IAsyncResult iar = ch.BeginSendToClient(message, new AsyncCallback(OnPushMessageComplete), new PushMessageState(ch, clientSessionId));
                if (iar.CompletedSynchronously)
                {
                    CompletePushMessage(iar);
                }
            }
            catch
            {
            }
        }
 internal PushMessageState(IUniversalDuplexCallbackContract channel, string session)
 {
     ch        = channel;
     sessionId = session;
 }
Beispiel #6
0
 public PushMessageState(IUniversalDuplexCallbackContract channel, string session)
 {
     Channel = channel;
     SessionId = session;
 }
Beispiel #7
0
 public PushMessageState(IUniversalDuplexCallbackContract channel, string session)
 {
     Channel   = channel;
     SessionId = session;
 }
Beispiel #8
0
        public void SendToService(DuplexMessage msg)
        {
            //We get here when we receive a message from a client
            IUniversalDuplexCallbackContract ch = OperationContext.Current.GetCallbackChannel <IUniversalDuplexCallbackContract>();
            string session = OperationContext.Current.Channel.SessionId;

            if (msg is ConnectMessage)
            {
                //lock (syncRoot)
                lock (clients)
                {
                    if (!clients.ContainsKey(session))  // new client
                    {
                        System.Diagnostics.Debug.WriteLine("New client connected: ");
                        System.Diagnostics.Debug.WriteLine("          " + (msg as ConnectMessage).NodeID);
                        System.Diagnostics.Debug.WriteLine("          " + (msg as ConnectMessage).TimeSeriesDataRootUrl);
                        System.Diagnostics.Debug.WriteLine("          " + (msg as ConnectMessage).CurrentDisplayType.ToString());
                        Client client = new Client();
                        client.Channel = ch;
                        client.NodeID  = (msg as ConnectMessage).NodeID;
                        client.TimeSeriesDataRootUrl    = (msg as ConnectMessage).TimeSeriesDataRootUrl;
                        client.RealTimeStatisticRootUrl = (msg as ConnectMessage).RealTimeStatisticRootUrl;
                        client.DataPointID        = (msg as ConnectMessage).DataPointID;
                        client.CurrentDisplayType = (msg as ConnectMessage).CurrentDisplayType;
                        clients.Add(session, client);
                        OperationContext.Current.Channel.Closing += Channel_Closing;
                        OperationContext.Current.Channel.Faulted += Channel_Faulted;
                        OnConnected(session);
                    }
                    else        //existing connected client. Just trying to update its settings.
                    {
                        clients[session] = new Client()
                        {
                            Channel                  = ch,
                            NodeID                   = (msg as ConnectMessage).NodeID,
                            DataPointID              = (msg as ConnectMessage).DataPointID,
                            TimeSeriesDataRootUrl    = (msg as ConnectMessage).TimeSeriesDataRootUrl,
                            RealTimeStatisticRootUrl = (msg as ConnectMessage).RealTimeStatisticRootUrl,
                            CurrentDisplayType       = (msg as ConnectMessage).CurrentDisplayType
                        };
                    }
                }

                Client currentClient = clients[session];
                // Initially when client is connected, we will send them data only if client is connected from home page of the openPDCManager.
                if (currentClient.CurrentDisplayType == DisplayType.Home)
                {
                    PushMessageToClient(session, new LivePhasorDataMessage()
                    {
                        //PmuDistributionList = CommonFunctions.GetPmuDistribution(),
                        DeviceDistributionList    = CommonFunctions.GetVendorDeviceDistribution(null, currentClient.NodeID),
                        InterconnectionStatusList = CommonFunctions.GetInterconnectionStatus(null, currentClient.NodeID)
                    }
                                        );

                    PushMessageToClient(session, new TimeSeriesDataMessage()
                    {
                        TimeSeriesData = CommonFunctions.GetTimeSeriesData(currentClient.TimeSeriesDataRootUrl + "/timeseriesdata/read/historic/" + currentClient.DataPointID.ToString() + "/*-30S/*/XML")
                                         //TimeSeriesData = CommonFunctions.GetTimeSeriesData(currentClient.TimeSeriesDataRootUrl + "current/" + currentClient.DataPointID.ToString() + "/XML")
                    }
                                        );
                }
                else if (currentClient.CurrentDisplayType == DisplayType.ServiceClient)
                {
                    if (serviceClientList.ContainsKey(currentClient.NodeID))
                    {
                        System.Diagnostics.Debug.WriteLine("Sending Cached Status to Client Connected on System Monitor Page.");
                        PushMessageToClient(session, new ServiceUpdateMessage()
                        {
                            ServiceUpdateType = UpdateType.Information,
                            ServiceUpdate     = serviceClientList[currentClient.NodeID].CachedStatus
                        });
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Sending Empty Message to Client Connected on System Monitor Page.");
                        PushMessageToClient(session, new ServiceUpdateMessage());
                    }
                }
                else if (currentClient.CurrentDisplayType == DisplayType.DeviceMeasurements)
                {
                    KeyValuePair <int, int> minMaxPointID = minMaxPointIDsPerNode[currentClient.NodeID];
                    if (!string.IsNullOrEmpty(currentClient.TimeSeriesDataRootUrl))     // if TimeSeriesDataRootUrl is defined for the node, then only try to send data to client upon connection.
                    {
                        System.Diagnostics.Debug.WriteLine("Sending Measurements to Client Connected on Device Measurements Page.");
                        PushMessageToClient(session, new TimeTaggedDataMessage()
                        {
                            TimeTaggedMeasurements = CommonFunctions.GetTimeTaggedMeasurements(currentClient.TimeSeriesDataRootUrl + "/timeseriesdata/read/current/" + minMaxPointID.Key.ToString() + "-" + minMaxPointID.Value.ToString() + "/XML")
                        });
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Sending Empty Message to Client Connected on Device Measurements Page.");
                        PushMessageToClient(session, new TimeTaggedDataMessage());
                    }
                }
                else if (currentClient.CurrentDisplayType == DisplayType.RealTimeStatistics)
                {
                    KeyValuePair <int, int> minMaxPointID = minMaxPointIDsPerNode[currentClient.NodeID];
                    if (!string.IsNullOrEmpty(currentClient.TimeSeriesDataRootUrl))     // if TimeSeriesDataRootUrl is defined for the node, then only try to send data to client upon connection.
                    {
                        System.Diagnostics.Debug.WriteLine("Sending Measurements to Client Connected on Device Measurements Page.");
                        PushMessageToClient(session, new TimeTaggedDataMessage()
                        {
                            TimeTaggedMeasurements = CommonFunctions.GetStatisticMeasurements(currentClient.RealTimeStatisticRootUrl + "/timeseriesdata/read/current/" + minMaxPointID.Key.ToString() + "-" + minMaxPointID.Value.ToString() + "/XML", currentClient.NodeID)
                        });
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Sending Empty Message to Client Connected on Device Measurements Page.");
                        PushMessageToClient(session, new TimeTaggedDataMessage());
                    }
                }
            }
            else if (msg is ServiceRequestMessage)
            {
                SendServiceRequest(clients[session].NodeID, (msg as ServiceRequestMessage).Request);
            }
            else if (msg is DisconnectMessage) //If it's a Disconnect message, treat as disconnection
            {
                ClientDisconnected(session);
            }
            else                //if (!(msg is ConnectMessage)) //Otherwise, if it's a payload-carrying message (and not just a simple "Connect"), process it
            {
                OnMessage(session, msg);
            }
        }