/// <summary> /// Remove client from the server. /// </summary> /// <param name="server"></param> /// <param name="client"></param> public static void Release(GXServer server, GXClient client) { lock (m_syncRoot) { try { if (client.Tracing) { server.Media.OnTrace -= new TraceEventHandler(client.media_OnTrace); client.Tracing = false; } } catch (Exception ex) { //Ignore if fails. System.Diagnostics.Debug.WriteLine(ex.Message); } int cnt = 0; lock (server.Clients.SyncRoot) { cnt = server.Clients.Count; } if (cnt == 1) { server.m_Sender.Closing.Set(); server.m_Receiver.Closing.Set(); server.m_SendThread.Join(); server.m_ReceiverThread.Join(); if (server.Media != null) { if (server.Media != null) { server.Media.Close(); } } server.Clients.Remove(client); m_instances.Remove(server.m_Name); } else { server.Clients.Remove(client); } } }
/// <summary> /// GXServer class factory. /// </summary> public static GXServer Instance(Gurux.Common.IGXMedia media, GXClient client) { lock (m_syncRoot) { if (m_instances == null) { m_instances = new Dictionary<string, GXServer>(); Handlers = new Dictionary<IGXEventHandler, object>(); } string name = media.Name; if (string.IsNullOrEmpty(name)) { name = media.MediaType; } GXServer server; if (m_instances.ContainsKey(name)) { server = m_instances[name]; if (server.m_bParseReceivedPacket != client.ParseReceivedPacket) { throw new Exception(Resources.ServerFailedToAcceptNewClientParseReceivedPacketValueIsInvalid); } if (!object.Equals(server.m_ReplyPacket.Eop, client.Eop)) { throw new Exception(Resources.ServerFailedToAcceptNewClientEopValueIsInvalid); } if (!object.Equals(server.m_ReplyPacket.Bop, client.Bop)) { throw new Exception(Resources.ServerFailedToAcceptNewClientBopValueIsInvalid); } if (server.m_ReplyPacket.ByteOrder != client.ByteOrder) { throw new Exception(Resources.ServerFailedToAcceptNewClientByteOrdersAreNotSame); } if (server.m_ReplyPacket.MinimumSize != client.MinimumSize) { throw new Exception(Resources.ServerFailedToAcceptNewClientMinimumSizeValueIsInvalid); } if (!server.m_ReplyPacket.ChecksumSettings.Equals(client.ChecksumSettings)) { throw new Exception(Resources.ServerFailedToAcceptNewClientChecksumSettingsAreNotSame); } lock (server.Clients.SyncRoot) { server.Clients.Add(client); } return server; } server = new GXServer(name); server.m_ReplyPacket = client.CreatePacket(); lock (server.Clients.SyncRoot) { server.Clients.Add(client); } server.m_bParseReceivedPacket = client.ParseReceivedPacket; media.OnClientDisconnected += new Gurux.Common.ClientDisconnectedEventHandler(server.OnClientDisconnected); media.OnClientConnected += new Gurux.Common.ClientConnectedEventHandler(server.OnClientConnected); media.OnError += new Gurux.Common.ErrorEventHandler(server.OnError); media.OnMediaStateChange += new Gurux.Common.MediaStateChangeEventHandler(server.OnMediaStateChange); media.OnReceived += new Gurux.Common.ReceivedEventHandler(server.OnReceived); server.m_Media = media; m_instances[name] = server; server.m_Sender = new GXServerSender(server); server.m_Receiver = new GXServerReceiver(server); server.m_SendThread = new Thread(new ThreadStart(server.m_Sender.Run)); server.m_SendThread.IsBackground = true; server.m_SendThread.Start(); server.m_ReceiverThread = new Thread(new ThreadStart(server.m_Receiver.Run)); server.m_ReceiverThread.IsBackground = true; server.m_ReceiverThread.Start(); return server; } }
/// <summary> /// Constructor. /// </summary> /// <param name="parent"></param> public GXServerReceiver(GXServer parent) { Parent = parent; }
/// <summary> /// Closes the connection to the GXCom. /// The used media is not closed, if there is more than one client that uses GXCom. /// The media is closed, when the last GXClient closes connection. /// It is recommended to use Close method, instead of MediaClose. /// </summary> /// <seealso cref="CloseMedia">CloseMedia</seealso> public void CloseServer() { if (m_Server != null) { NotifyVerbose(this, Resources.ClientClosesServer); GXServer.Release(m_Server, this); m_Server = null; NotifyUnload(); } }
/// <summary> /// Assigns new media, after media settings are changed. /// </summary> /// <remarks> /// The media must be created before calling this method. /// See methods EnumMedias and SelectMedia. /// Active media is implemented with GetCurrentMedia method. /// AssignMedia closes the active media and selects a new one. /// The protocol settings do not change, when AssignMedia is called. /// After AssignMedia is called, the media must be opened with MediaOpen method. /// The new media is selected with the SelectMedia method. /// </remarks> /// <param name="media">New media component.</param> /// <seealso cref="SelectMedia">SelectMedia</seealso> /// <seealso cref="Properties">Properties</seealso> public void AssignMedia(Gurux.Common.IGXMedia media) { IGXMediaContainer tmp = media as IGXMediaContainer; if (tmp != null) { media = (media as IGXMediaContainer).Media; media.MediaContainer = tmp; } CloseServer(); m_MediaType = ""; if (media != null) { if (media != null) { m_MediaType = media.MediaType; m_MediaSettings = media.Settings; } if (m_MediaSettings != null) { m_MediaSettings = m_MediaSettings.Replace("\r\n", ""); } NotifyLoad(); //Notify that media is changed. NotifyMediaStateChange(MediaState.Changed); m_Server = GXServer.Instance(media, this); //If handler is given before server is up. if (Handler != null) { m_Server.AddEventHandler(Handler, Clients); Handler = null; Clients = null; } //Notify is media is already open. if (media.IsOpen) { NotifyMediaStateChange(MediaState.Open); } } }
/// <summary> /// Constructor. /// </summary> /// <param name="parent"></param> public GXServerSender(GXServer parent) { Parent = parent; }