private void DisconnectNotifyBroadcast(string disconnectedKey, Connection disconnected, string initiatorUniqueKey, List <Connection> clients, string reason, bool kill) { BroadcastsChannel.ConnectDisconnected(disconnectedKey, initiatorUniqueKey, clients, reason, kill); var cC = disconnected.ServerChannel as ICommunicationObject; if (cC != null && cC.State == CommunicationState.Opened) { // the following cC.Close(); will interrupt overall broadcasting // therefore disconnected should be notified personally try { disconnected.BroadcastChannel <T>().ConnectDisconnected(disconnectedKey, initiatorUniqueKey, clients, reason, kill); } catch (SystemException) { } // closing is vital because without closing client will be only notified // but it can continue to work Channels.CloseChannel(ref cC); } //was Unsubscribe(null, (T) disconnected.ServerChannel); in 1.0.0.0 }
public string Restart() { // since this method can be called from GeneralMessage(...) ClaimsPolicy.ServerMethodCheck(typeof(IContract).GetMethod(MethodBase.GetCurrentMethod().Name)); //1. Server broadcasts to clients about start of technical restart BroadcastsChannel.ServerRestarted(false, Sender.ClientUniqueKey); //2. Clients have to pause all their network activities //3. Server blocks all incoming requests from clients, but server finishes all current activities – it does not abort them. //4. Server stores list of clients connected (sClients) and other internal data like ChatRooms, RecordLocks etc //5. Windows service is stopped without clients disconnecting (but their channels are broken) //6. New binaries are copied //7. Windows service is started //8. New Server allows incoming requests for connection only from previously connected clients (sClients) //9. Server waits till 10 seconds until all sClients will be reconnected //10. Server restores previous internal data for clients that were reconnected successfully. //11. Server allows all incoming requests from clients. //12. Server broadcasts to clients about end of technical restart BroadcastsChannel.ServerRestarted(true, Sender.ClientUniqueKey); return(null); }
public DateTime?TimeRequest(string workstationApplied, string workstationReturn, DateTime?setDate) { DateTime?actualTime = null; if (setDate == null) { if (string.IsNullOrEmpty(workstationApplied) || workstationApplied.ToUpper() == Environment.MachineName.ToUpper()) { actualTime = DateTime.Now; GetClients(workstationReturn) .ForEach(a => { try { a.BroadcastChannel <T>().TimeGet(false, actualTime, Server.UniqueKey); } catch (SystemException) { PuntUser(a, "bad connection"); } }); } else { // time may be got only from ONE workstation // this is server GetClients(workstationApplied) .ForEach(a => { try { a.BroadcastChannel <T>().TimeGet(true, null, Sender.ClientUniqueKey); } catch (SystemException) { PuntUser(a, "bad connection"); } }); } } else { if (string.IsNullOrEmpty(workstationApplied) || workstationApplied.ToUpper() == Environment.MachineName.ToUpper()) { if (DateUtils.SetLocalTime((DateTime)setDate)) { actualTime = setDate; GetClients(workstationReturn) .ForEach(a => { try { a.BroadcastChannel <T>().TimeSet(false, (DateTime)actualTime, Server.UniqueKey); } catch (SystemException) { PuntUser(a, "bad connection"); } }); } else { throw new ApplicationException("unsuccessful time setting on server"); } } var l = new List <Connection>(); if (string.IsNullOrEmpty(workstationApplied)) { l = RequestUsers(); BroadcastsChannel.TimeSet(true, (DateTime)setDate, Sender.ClientUniqueKey); } else if (workstationApplied.ToUpper() != Environment.MachineName.ToUpper()) { l = GetClients(workstationApplied); } l.ForEach(a => { try { a.BroadcastChannel <T>().TimeSet(true, (DateTime)setDate, Sender.ClientUniqueKey); } catch (SystemException) { PuntUser(a, "bad connection"); } }); } return(actualTime); }