Recieve message from external system in EventServer plugin

We decided try to use the message “Milestone” and faced with a problem of recieve messages on the side of “EventServer” plug-in.

Event Server plug-in code (BackgroundPlugin.cs):

...
public class EmptyMessageIdFilter : MessageFilter 
{
	private string _filter; 
	public EmptyMessageIdFilter(string messageId = null) 
	{
		_filter = messageId; 
	}
	public override bool Match(Message message, FQID destination, FQID sender) 
	{ 
		return true; 
	} 
} 
...
public override void Init() 
{ 
	_regEvents = new List<object>();
	MessageCommunicationManager.Start(EnvironmentManager.Instance.MasterSite.ServerId);
	_messageCommunication = MessageCommunicationManager.Get(EnvironmentManager.Instance.MasterSite.ServerId);
	foreach (string evt in Properties.Settings.Default.MessageIds) 
	{ 
		_regEvents.Add(_messageCommunication.RegisterCommunicationFilter(EventHandler, new CommunicationIdFilter(evt)));
	} 
	_msgRef = EnvironmentManager.Instance.RegisterReceiver(EventHandler, new EmptyMessageIdFilter());
	_msgRef2 = EnvironmentManager.Instance.RegisterReceiver(EventHandler, new MessageIdListFilter(Properties.Settings.Default.MessageIds.Cast<string>().ToArray())); 
} 
private object EventHandler(Message message, FQID f1, FQID f2) // Don't recieve message with ID from MessageID list 
{
	return null; 
} 
...

Event Server plug-in code (Definition.cs​):

... 
public override List<string> PluginDefinedMessageIds 
{ 
	get 
	{ 
		return Properties.Settings.Default.MessageIds.Cast<string>().ToList(); 
	} 
} 
...

However, in other systems approach works fine.

SomeSystem handle and send message code:

...
public delegate void XProtectEvent(string EventName, string Data);
public static event XProtectEvent OnXProtectEvent; private Dictionary<string, object> _inputEvents;
private MessageCommunication _messageCommunication; 
public static void Connect(string EventServerHostname, string user, string passwd, List<string> inEvents) 
{ 
	try 
	{ 
		VideoOS.Platform.SDK.Environment.Initialize(); 
		Uri uri = new UriBuilder(EventServerHostname).Uri; 
		VideoOS.Platform.SDK.Environment.AddServer(uri, new NetworkCredential(user, passwd)); 
		VideoOS.Platform.SDK.Environment.Login(uri); 
		MessageCommunicationManager.Start(EnvironmentManager.Instance.MasterSite.ServerId); 
		_instance._messageCommunication = MessageCommunicationManager.Get(EnvironmentManager.Instance.MasterSite.ServerId); 
		foreach(string evt in inEvents) 
		{ 
			_instance._inputEvents[evt] = _instance._messageCommunication.RegisterCommunicationFilter(XProtectEventHandler, new CommunicationIdFilter(evt));
			Driver.Log("Subscribed to Milestone XProtect event {0} at {1}", evt, EventServerHostname); 
		} 
	} 
	catch (Exception e) 
	{ 
		Driver.Log(LogType.Error, e.ToString()); 
	} 
} 
private static object XProtectEventHandler(Message message, FQID destination, FQID sender) 
{ 
	if (OnXProtectEvent != null && !String.IsNullOrEmpty((String)message.Data)) 
	{ 
		OnXProtectEvent(message.MessageId, (String)message.Data);
	} 
	return new object(); 
} 
public static bool SendEvent(string EventName, string EventData) 
{ 
	bool IsSucces; 
	if (String.IsNullOrEmpty(EventName) || String.IsNullOrEmpty(EventData)) 
	{ 
		return false; 
	} 
	try 
	{ 
		_instance._messageCommunication.TransmitMessage(new VideoOS.Platform.Messaging.Message(EventName, EventData), null, null, null); 
		IsSucces = true;
	} 
	catch (Exception e) 
	{ 
		Driver.Log(LogType.Error, e.Message);
		IsSucces = false;
	} 
	return IsSucces; 
}
...

Two our systems perfectly communicate with each other in this way.

For SDK we created a sample user in Windows (non-participating in windows groups), created role in milestone and add this user in milestone with created role

What could be the problem?

Maybe you just need to wait a bit and verify the MessageCommunication IsConnected.

If you have two systems that works fine and one which fails you should perhaps go into what is different.

Does the Chat sample work for you?

MessageCommunication instance

IsConnected = true.

The only difference is that our systems is not a plugins to “EventServer”) Methods of connection, receiving and transmitting are the same.

Chat sample works fine.

I changed plugin target from service to SmartClient and run client, plugin fine recieve and send message.

But we need to this plugin permanently working in the background.

We think we need to see your plugin and debug it while running, we hope we can persuade you to open a Support Case and send the project to Milestone Technical Support for analysis. As a Milestone Solution Partner you can login and submit the support case via the partner portal.

Bo, we created a case MSC174898, but I did not understand how to attach the project files to case.

You cannot attach a file when you create the support case , but when you later “manage” the case you can. Thank you.

(PS. I have indicated an alternative on the case just in case..)

After some debugging I was able to find out what was wrong.

Our investigations show that MessageCommunication is not ready for use when started in the BackgroundPlugin - Init()

The solution was to subscribe to the ConfigurationChangedIndication event. The event will always happen at start-up when the Event Server has successfully loaded all configuration from the XProtect.

Modify your BackgroundPlugin Init() to include this. –

_msgRef2 = EnvironmentManager.Instance.RegisterReceiver(ConfigChangedHandler, new MessageIdFilter(VideoOS.Platform.Messaging.MessageId.Server.ConfigurationChangedIndication));

Then create the handler, in the handler start the MessageCommunication and register communication filters, with your code as the example it would look like:

private object ConfigChangedHandler(Message message, FQID destination, FQID sender) 
{ 
if (_msgRef == null) 
{ 
MessageCommunicationManager.Start(EnvironmentManager.Instance.MasterSite.ServerId); 
_messageCommunication = MessageCommunicationManager.Get(EnvironmentManager.Instance.MasterSite.ServerId); 
foreach (string evt in Properties.Settings.Default.APSIMMessageIds) 
{ 
_regEvents[evt] = _messageCommunication.RegisterCommunicationFilter(APSIMEventHandler, new CommunicationIdFilter(evt)); 
MsLogger.Log("Register Communication Filter: " + evt); 
} 
_msgRef = EnvironmentManager.Instance.RegisterReceiver(NewEventHandler, new EmptyMessageIdFilter()); 
} 
return null; 
}