/// <summary> /// Constructor. /// </summary> /// <param name="port">The port for the server of the bus. Leave null for default port.</param> /// <param name="accessControl">Control requirements for user and password for connecting clients, pass null for no control (everyone can connect).</param> public ServerMessageBus(string name, int? port, ServerAccessControl accessControl) : base(name) { AccessControl = accessControl; if (port.HasValue == false) { port = DefaultPort; } _server = new SocketMessageServer(base.Serializer); _server.Start(new IPEndPoint(IPAddress.Any, port.Value)); _server.ClientAsyncMessageSendEvent += new SocketMessageServer.AsyncMessageSendUpdateDelegate(_server_ClientAsyncMessageSendEvent); _server.ClientConnectedEvent += new SocketMessageServer.ServerClientUpdateDelegate(_server_ClientConnectedEvent); _server.ClientDisconnectedEvent += new SocketMessageServer.ServerClientUpdateDelegate(_server_ClientDisconnectedEvent); _server.ClientMessageReceivedEvent += new SocketMessageServer.MessageUpdateDelegate(_server_ClientMessageReceivedEvent); ApplicationLifetimeHelper.ApplicationClosingEvent += new CommonHelper.DefaultDelegate(ApplicationLifetimeHelper_ApplicationClosingEvent); }
void _server_ClientMessageReceivedEvent(SocketMessageServer server, SocketCommunicatorEx client, object message) { ServerAccessControl accessControl = AccessControl; // Check security first. if (accessControl != null && message is AccessMessage == false) { if (accessControl.IsAllowed(ObtainClientAccessControl(client.Id)) == false) { #if Matrix_Diagnostics InstanceMonitor.Info("Message [" + message.ToString() +"] from client [" + client.ToString() + "] not allowed due to access control.", TracerItem.PriorityEnum.Medium); #endif return; } } if (message is EnvelopeMessage) {// Envelope user message. EnvelopeMessage envelopeMessage = (EnvelopeMessage)message; // Remove the remote message bus index association. envelopeMessage.Sender.LocalMessageBusIndex = ClientId.InvalidMessageBusClientIndex; foreach (ClientId id in envelopeMessage.Receivers) { // Assign the id as local id, if it is, otherwise skip it. id.LocalMessageBusIndex = base.GetClientIndexByGuid(id.Guid); if (id.IsMessageBusIndexValid) { id.MessageBus = this; if (DoSendToClient(envelopeMessage.Sender, id, envelopeMessage.Envelope, null) != SendToClientResultEnum.Success) { #if Matrix_Diagnostics InstanceMonitor.OperationError(string.Format("Failed to accept envelope message [{0}].", envelopeMessage.ToString())); #endif } } else { #if Matrix_Diagnostics InstanceMonitor.OperationError(string.Format("Failed to accept envelope message [{0}] due unrecognized receiver id.", envelopeMessage.ToString())); #endif } } } else if (message is ClientsListMessage) {// Message bus system message. ClientsListMessage updateMessage = (ClientsListMessage)message; for (int i = 0; i < updateMessage.Ids.Count; i++) { RegisterClientId(client.Id, updateMessage.Ids[i], updateMessage.Types[i], updateMessage.SourcesTypes[i]); } } else if (message is RequestClientListUpdateMessage) { SendClientsUpdate(client.Id); } else if (message is ClientUpdateMessage) { ClientUpdateMessage updateMessage = (ClientUpdateMessage)message; bool validClient; lock (_syncRoot) { validClient = _remoteClientNetId.ContainsKey(updateMessage.ClientId); } if (validClient) { RaiseClientAddedEvent(updateMessage.ClientId); } else { #if Matrix_Diagnostics InstanceMonitor.OperationError(string.Format("Failed to raise update event for client [{0}], since client not found.", updateMessage.ClientId.ToString())); #endif } } else if (message is AccessMessage) { ClientAccessControl control = ObtainClientAccessControl(client.Id); if (control != null) { control.Update(message as AccessMessage); } } else if (message is StateUpdateMessage) { RaiseCounterPartyUpdateEvent("Client:" + client.Id.ToString(), ((StateUpdateMessage)message).State.ToString()); } else { #if Matrix_Diagnostics InstanceMonitor.Warning(string.Format("Message [{0}] not recognized.", message.GetType().Name)); #endif } }
void _server_ClientDisconnectedEvent(SocketMessageServer server, SocketCommunicatorEx client) { // Clear all clients hooked on this connection. ListUnique<ClientId> clientsIds = null; lock (_syncRoot) { if (_remoteClientsNetIds.TryGetByKey(client.Id, ref clientsIds) == false) { return; } _clientsAccessControl.Remove(client.Id); _remoteClientsNetIds.RemoveByKey(client.Id); foreach (ClientId id in clientsIds) { _remoteClientNetId.Remove(id); _remoteClientsTypes.Remove(id); _remoteClientsSourcesTypesNames.Remove(id); } } // Raise event to notify of the disconnection of all these Ids. foreach (ClientId id in clientsIds) { // Notify of clients removal, with non permanent remove, since they may later be restored. RaiseClientRemovedEvent(id, false); } }
void _server_ClientConnectedEvent(SocketMessageServer server, SocketCommunicatorEx client) { // The client expects is, so activate keep alive. client.KeepAlive = true; // Send local bus clients info to connected element. // Important - this will also be sent even to clients that do not have verified access control. if (SendClientsUpdate(client.Id) == false) { #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to send clients update to client [" + client.ToString() + ", " + client.Id + "]."); #endif } }
void _server_ClientAsyncMessageSendEvent(SocketMessageServer server, SocketCommunicatorEx client, SocketCommunicator.AsyncMessageSendInfo info) { // A message has been successfully sent to client. }
public override void Dispose() { ApplicationLifetimeHelper.ApplicationClosingEvent -= new CommonHelper.DefaultDelegate(ApplicationLifetimeHelper_ApplicationClosingEvent); SocketMessageServer server = _server; _server = null; if (server != null) { server.ClientAsyncMessageSendEvent -= new SocketMessageServer.AsyncMessageSendUpdateDelegate(_server_ClientAsyncMessageSendEvent); server.ClientConnectedEvent -= new SocketMessageServer.ServerClientUpdateDelegate(_server_ClientConnectedEvent); server.ClientDisconnectedEvent -= new SocketMessageServer.ServerClientUpdateDelegate(_server_ClientDisconnectedEvent); server.ClientMessageReceivedEvent -= new SocketMessageServer.MessageUpdateDelegate(_server_ClientMessageReceivedEvent); server.Stop(TimeSpan.FromSeconds(2)); server.Dispose(); } base.Dispose(); }