/// If a remote application sends a message, the registered callback function of the local port is called.
/// The trusted message-port API allows communications between applications that are signed by the same developer(author) certificate.
/// </remarks>
- public class MessagePort
+ public class MessagePort : IDisposable
{
- private static Dictionary<MessagePort, int> s_portMap = new Dictionary<MessagePort, int>();
+ private static object s_lock = new object();
+ private static HashSet<string> s_portMap = new HashSet<string>();
/// <summary>
/// Constructor
{
StopListening();
}
+ Dispose(false);
}
/// <summary>
/// </summary>
public void Listen()
{
- if (!s_portMap.ContainsKey(this))
+ lock(s_lock)
{
- _messageCallBack = (int localPortId, string remoteAppId, string remotePortName, bool trusted, IntPtr message, IntPtr userData) =>
+ if (s_portMap.Contains(_portName))
{
- Bundle bundle = new Bundle(message);
- MessageReceivedEventArgs args;
+ throw new InvalidOperationException(_portName + " is already used");
+ }
+ _messageCallBack = (int localPortId, string remoteAppId, string remotePortName, bool trusted, IntPtr message, IntPtr userData) => {
+ MessageReceivedEventArgs args = new MessageReceivedEventArgs() {
+ Message = new Bundle(message)
+ };
- if (!String.IsNullOrEmpty(remotePortName))
- {
- args = new MessageReceivedEventArgs(bundle, remoteAppId, remotePortName, trusted);
- }
- else
+ if (!String.IsNullOrEmpty(remotePortName) && !String.IsNullOrEmpty(remoteAppId))
{
- args = new MessageReceivedEventArgs(bundle);
+ args.Remote = new RemoteValues() {
+ AppId = remoteAppId,
+ PortName = remotePortName,
+ Trusted = trusted
+ };
}
-
RaiseMessageReceivedEvent(MessageReceived, args);
};
- if (_trusted)
- {
- _portId = Interop.MessagePort.RegisterTrustedPort(_portName, _messageCallBack, IntPtr.Zero);
- }
- else
- {
- _portId = Interop.MessagePort.RegisterPort(_portName, _messageCallBack, IntPtr.Zero);
- }
+ _portId = _trusted ?
+ Interop.MessagePort.RegisterTrustedPort(_portName, _messageCallBack, IntPtr.Zero) :
+ Interop.MessagePort.RegisterPort(_portName, _messageCallBack, IntPtr.Zero);
- if (_portId > 0)
- {
- s_portMap.Add(this, 1);
- _listening = true;
- }
- else
- {
- MessagePortErrorFactory.ThrowException(_portId);
- }
- }
- else
- {
- MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidOperation, "Already listening");
+ if (_portId <= 0)
+ throw new InvalidOperationException("Can't Listening with " + _portName);
+
+ s_portMap.Add(_portName);
+ _listening = true;
}
}
/// </summary>
public void StopListening()
{
- if (_listening)
+ if (!_listening)
{
- int ret;
- if (_trusted)
- {
- ret = Interop.MessagePort.UnregisterTrustedPort(_portId);
- }
- else
- {
- ret = Interop.MessagePort.UnregisterPort(_portId);
- }
+ throw new InvalidOperationException("Already stopped");
+ }
- if (ret == (int)MessagePortError.None)
- {
- s_portMap.Remove(this);
- _portId = 0;
- _listening = false;
- }
- else
- {
- MessagePortErrorFactory.ThrowException(ret);
- }
+ int ret = _trusted ?
+ Interop.MessagePort.UnregisterTrustedPort(_portId) :
+ Interop.MessagePort.UnregisterPort(_portId);
+
+ if (ret != (int)MessagePortError.None)
+ {
+ MessagePortErrorFactory.ThrowException(ret);
}
- else
+
+ lock(s_lock)
{
- MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidOperation, "Already stopped");
+ s_portMap.Remove(_portName);
}
+ _portId = 0;
+ _listening = false;
}
/// <summary>
/// <param name="trusted">If true the trusted message port of remote application otherwise false</param>
public void Send(Bundle message, string remoteAppId, string remotePortName, bool trusted = false)
{
- if (_listening)
+ if (!_listening)
{
- int ret;
- if (trusted)
- {
- ret = Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId);
- }
- else
- {
- ret = Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId);
- }
+ throw new InvalidOperationException("Sould start listen before send");
+ }
+ int ret = trusted ?
+ Interop.MessagePort.SendTrustedMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId) :
+ Interop.MessagePort.SendMessageWithLocalPort(remoteAppId, remotePortName, message.Handle, _portId);
- if (ret != (int)MessagePortError.None)
+ if (ret != (int)MessagePortError.None)
+ {
+ if (ret== (int)MessagePortError.MaxExceeded)
{
- if (ret== (int)MessagePortError.MaxExceeded)
- {
- MessagePortErrorFactory.ThrowException(ret, "Message has exceeded the maximum limit(4KB)", "Message");
- }
- else
- {
- MessagePortErrorFactory.ThrowException(ret);
- }
+ MessagePortErrorFactory.ThrowException(ret, "Message has exceeded the maximum limit(4KB)", "Message");
}
- }
- else
- {
- MessagePortErrorFactory.ThrowException((int)MessagePortError.InvalidOperation, "Need listening");
+ MessagePortErrorFactory.ThrowException(ret, "Can't send message");
}
}
- /// <summary>
- /// Override GetHashCode
- /// </summary>
- /// <returns></returns>
- public override int GetHashCode()
+ private void RaiseMessageReceivedEvent(EventHandler<MessageReceivedEventArgs> evt, MessageReceivedEventArgs args)
{
- int hash = 0;
- if (!String.IsNullOrEmpty(_portName))
+ if (evt != null)
{
- hash ^= _portName.GetHashCode();
+ evt(this, args);
}
- hash ^= _trusted.GetHashCode();
- return hash;
}
- /// <summary>
- /// Override Equals
- /// </summary>
- /// <param name="obj"></param>
- /// <returns></returns>
- public override bool Equals(object obj)
+ protected virtual void Dispose(bool disposing)
{
- MessagePort p = obj as MessagePort;
- if (p == null)
+ if (_listening)
{
- return false;
+ StopListening();
}
- return (_portName == p._portName) & (_trusted == p._trusted);
}
- private void RaiseMessageReceivedEvent(EventHandler<MessageReceivedEventArgs> evt, MessageReceivedEventArgs args)
+ public void Dispose()
{
- if (evt != null)
- {
- evt(this, args);
- }
+ Dispose(true);
+ GC.SuppressFinalize(this);
}
+
}
}
\ No newline at end of file