Listen to client requests from Server SDK

Questions regarding the use of the .NET SDK 2.0 for Server or Client development or integration into customer products ...

Moderator: uasdknet

Post Reply
jramirez-jh
Sr. Member
Sr. Member
Posts: 16
Joined: 14 Jun 2021, 23:39

Listen to client requests from Server SDK

Post by jramirez-jh »

I need to do some basic logging (with a custom logging provider) of what a client (Session) is doing like reading or writing. I am not sure what is the easiest way of doing this? Is there any global event or Session attached event that I can listen?

The info I need to log is:

* the ID or Name of the Client (Session)
* the performed request (read/write)
* the name of target Node/variable/attribute
* the data sent (in case of writing) from the client
* the current value (when writing) of the target node/variable/attribute

jramirez-jh
Sr. Member
Sr. Member
Posts: 16
Joined: 14 Jun 2021, 23:39

Re: Listen to client requests from Server SDK

Post by jramirez-jh »

In case any future user requires the same, the solution is to override the following methods in your ServerManager implementation:

For Sync scenarios:

Code: Select all

protected override ResponseHeader OnRequestComplete(RequestContext context)
protected override ResponseHeader OnRequestError(RequestContext context, Exception e)
For Async scenarios:

Code: Select all

protected override void OnAsyncRequestComplete(RequestContext context, IEndpointIncomingRequest incoming, bool doNotBlockThread)
protected override void OnAsyncRequestError(RequestContext context, IEndpointIncomingRequest incoming, bool doNotBlockThread, Exception e)
I would have preferred them to be events, but it is what it is.

jramirez-jh
Sr. Member
Sr. Member
Posts: 16
Joined: 14 Jun 2021, 23:39

Re: Listen to client requests from Server SDK

Post by jramirez-jh »

I'm struggling a lot trying to obtain the NodeId for a MonitoredItem when a request of type PUBLISH is completed. The only info I can see is the current/new value (DataValue) asssigned for the MonitoredItem but no info about the object itself.

My current code (not working as needed):

Code: Select all

protected override void OnAsyncRequestComplete(RequestContext context, IEndpointIncomingRequest incoming, bool doNotBlockThread)
{
	var client = context.Session.SessionName; //Client being notified
	
	switch (context.RequestType)
	{
		case ServiceType.Publish:
		
			var pubResponse = incoming.Response as PublishResponse;

			foreach (var nd in pubResponse.NotificationMessage.NotificationData)
			{							
				var body = nd.Body as DataChangeNotification;

				foreach (var mi in body.MonitoredItems)
				{
					//var itemName = mi.NodeId; //<-- I need to find info related to the NodeId being modified (display name, namespace etc). 
					var itemValue = mi.Value.ToString();
				}
			}
			break;
	}

	base.OnAsyncRequestComplete(context, incoming, doNotBlockThread);
}
I will appreciate your assistance

jramirez-jh
Sr. Member
Sr. Member
Posts: 16
Joined: 14 Jun 2021, 23:39

Re: Listen to client requests from Server SDK

Post by jramirez-jh »

jramirez-jh wrote:
07 Dec 2021, 09:38
I'm struggling a lot trying to obtain the NodeId for a MonitoredItem when a request of type PUBLISH is completed. The only info I can see is the current/new value (DataValue) asssigned for the MonitoredItem but no info about the object itself.

My current code (not working as needed):

Code: Select all

protected override void OnAsyncRequestComplete(RequestContext context, IEndpointIncomingRequest incoming, bool doNotBlockThread)
{
	var client = context.Session.SessionName; //Client being notified
	
	switch (context.RequestType)
	{
		case ServiceType.Publish:
		
			var pubResponse = incoming.Response as PublishResponse;

			foreach (var nd in pubResponse.NotificationMessage.NotificationData)
			{							
				var body = nd.Body as DataChangeNotification;

				foreach (var mi in body.MonitoredItems)
				{
					//var itemName = mi.NodeId; //<-- I need to find info related to the NodeId being modified (display name, namespace etc). 
					var itemValue = mi.Value.ToString();
				}
			}
			break;
	}

	base.OnAsyncRequestComplete(context, incoming, doNotBlockThread);
}
I will appreciate your assistance
Again replying to myself: the answer is to use the pubResponse.SubscriptionId and the mi.ClientHandle to query against the SubscriptionManager.

Code: Select all

var subs = SubscriptionManager.GetSubscription(context, pubResponse.SubscriptionId);
var mi = subs.GetMonitoredItem(mi.ClientHandle);
return mi.NodeId;
Thanks to me for wasting a lot of time searching in the pretty-bad-documented code base.

Post Reply