/// <summary> /// It will send all connected clients a specific message /// </summary> /// <param name="cmdCode">can be one of the <code>eResponseTypes</code> codes or any user defined codes</param> /// <param name="content">can be null</param> /// <param name="excludedAgent">message will not be sent to this specific agent, can be null</param> /// <param name="desc"></param> public void BroadcastMessage(int cmdCode, string content, AgentRelay excludedAgent) { lock (m_Agents) { foreach (AgentRelay agent in m_Agents) { if (agent == null || agent.IsFaulty) { continue; } try { if (excludedAgent != null && excludedAgent == agent) { continue; } if (content == null) { agent.SendPacket(cmdCode); } else { agent.SendPacket(cmdCode, content); } } catch { } } } }
public static AgentRelay FromClient(TcpClient client) { AgentRelay relay = new AgentRelay(); relay.m_TcpClient = client; relay.m_RawSocket = client.Client; relay.StartWorker(); return(relay); }
private void Listener_OnNewPacketReceived(AgentRelay.Packet packet, AgentRelay listener) { PackageOn((TcpCommands)packet.Command, AgentRelay.MakeStringFromPacketContents(packet)); switch (packet.Command) { case (byte)TcpCommands.ClientHello: if (!dictionaryAgents.ContainsKey(listener.Guid)) { var _login = AgentRelay.MakeStringFromPacketContents(packet); dictionaryAgents.TryAdd(listener.Guid, null); var _user = context.USERS.ToList().Find(u => u.USER_LOGIN == _login); if (_user != null) { dictionaryAgents[listener.Guid] = new User { Login = _user.USER_LOGIN, Hash = _user.USER_HASH, Content = _user, CurrentMemoir = 0, TotalMemoir = _user.MEMOIRS.Count - 1 }; } else { dictionaryAgents[listener.Guid] = new User { Login = _login, CurrentMemoir = 0, TotalMemoir = 0 }; } NewAgentСonnected("New Agent Сonnected! GUID -> " + listener.Guid + ", User login -> " + dictionaryAgents[listener.Guid].Login + ", Date -> " + DateTime.Now); listener.SendPacket((byte)TcpCommands.ServerHello); } break; case (byte)TcpCommands.ClientLoginQuery: string hash = GetHash(AgentRelay.MakeStringFromPacketContents(packet)); if (dictionaryAgents[listener.Guid].Hash != null) { if (dictionaryAgents[listener.Guid].Hash == hash) { dictionaryAgents[listener.Guid].Verified = true; listener.SendPacket((byte)TcpCommands.ServerLoginOK); return; } else { listener.SendPacket((byte)TcpCommands.ServerLoginFailed, "Неправильный пароль."); return; } } listener.SendPacket((byte)TcpCommands.ServerLoginFailed, "Такой пользователь не зарегистрирован."); break; case (byte)TcpCommands.ClientGetDataQuery: if (dictionaryAgents[listener.Guid].Verified) { int counter = 0; foreach (var memoir in dictionaryAgents[listener.Guid].Content.MEMOIRS) { listener.SendPacket((byte)TcpCommands.ServerGetDataMarkMemoirResponse, counter.ToString()); listener.SendPacket((byte)TcpCommands.ServerGetDataMarkResponse, new byte[] { (byte)CurrentMemoirField.MEMOIR_DATE_CHANGE }); listener.SendPacket((byte)TcpCommands.ServerGetDataResponse, memoir.MEMOIR_DATE_CHANGE.ToString()); listener.SendPacket((byte)TcpCommands.ServerGetDataMarkResponse, new byte[] { (byte)CurrentMemoirField.MEMOIR_TEXT }); listener.SendPacket((byte)TcpCommands.ServerGetDataResponse, memoir.MEMOIR_TEXT); listener.SendPacket((byte)TcpCommands.ServerGetDataMarkResponse, new byte[] { (byte)CurrentMemoirField.MEMOIR_ID }); listener.SendPacket((byte)TcpCommands.ServerGetDataResponse, memoir.MEMOIR_ID.ToString()); listener.SendPacket((byte)TcpCommands.ServerGetDataMarkResponse, new byte[] { (byte)CurrentMemoirField.MEMOIR_TITLE }); listener.SendPacket((byte)TcpCommands.ServerGetDataResponse, memoir.MEMOIR_TITLE); counter++; } listener.SendPacket((byte)TcpCommands.ServerOK); return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientMarkFieldQuery: if (dictionaryAgents[listener.Guid].Verified) { byte mark = packet.Content[0]; switch (mark) { case (byte)CurrentMemoirField.MEMOIR_TEXT: dictionaryAgents[listener.Guid].CurrentField = CurrentMemoirField.MEMOIR_TEXT; break; case (byte)CurrentMemoirField.MEMOIR_DATE_CHANGE: dictionaryAgents[listener.Guid].CurrentField = CurrentMemoirField.MEMOIR_DATE_CHANGE; break; case (byte)CurrentMemoirField.MEMOIR_ID: dictionaryAgents[listener.Guid].CurrentField = CurrentMemoirField.MEMOIR_ID; break; case (byte)CurrentMemoirField.MEMOIR_TITLE: dictionaryAgents[listener.Guid].CurrentField = CurrentMemoirField.MEMOIR_TITLE; break; } return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientMarkTotalMemoirQuery: if (dictionaryAgents[listener.Guid].Verified) { int total = Convert.ToInt32(AgentRelay.MakeStringFromPacketContents(packet)); if (dictionaryAgents[listener.Guid].TotalMemoir < total) { dictionaryAgents[listener.Guid].Content.MEMOIRS.Add(new MEMOIRS() { MEMOIR_DATE_RECORD = DateTime.Now }); dictionaryAgents[listener.Guid].TotalMemoir++; } return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientMarkCurrentMemoirQuery: if (dictionaryAgents[listener.Guid].Verified) { int current = Convert.ToInt32(AgentRelay.MakeStringFromPacketContents(packet)); dictionaryAgents[listener.Guid].CurrentMemoir = current; return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientUpdateEndQuery: if (dictionaryAgents[listener.Guid].Verified) { try { context.SaveChanges(); listener.SendPacket((byte)TcpCommands.ServerOK, "Данные записаны."); return; } catch (Exception ex) { } } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientUpdateDataQuery: if (dictionaryAgents[listener.Guid].Verified) { string content = AgentRelay.MakeStringFromPacketContents(packet); var listMemoir = dictionaryAgents[listener.Guid].Content.MEMOIRS.ToList(); var memoir = listMemoir[dictionaryAgents[listener.Guid].CurrentMemoir]; switch (dictionaryAgents[listener.Guid].CurrentField) { case CurrentMemoirField.MEMOIR_TEXT: memoir.MEMOIR_TEXT = content; break; case CurrentMemoirField.MEMOIR_DATE_CHANGE: memoir.MEMOIR_DATE_CHANGE = Convert.ToDateTime(content); break; case CurrentMemoirField.MEMOIR_TITLE: memoir.MEMOIR_TITLE = content; break; } return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientDeleteDataQuery: if (dictionaryAgents[listener.Guid].Verified) { var memoir = from mem in dictionaryAgents[listener.Guid].Content.MEMOIRS where mem.MEMOIR_ID == Convert.ToInt64(AgentRelay.MakeStringFromPacketContents(packet)) select mem; if (memoir.Count() == 0) { listener.SendPacket((byte)TcpCommands.ServerFailed, "Такая запись не существует."); return; } context.MEMOIRS.Remove(memoir.First()); context.SaveChanges(); dictionaryAgents[listener.Guid].TotalMemoir--; listener.SendPacket((byte)TcpCommands.ServerOK, "Воспаминание удаленно."); return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientDeleteDataLastQuery: if (dictionaryAgents[listener.Guid].Verified) { var memoir = dictionaryAgents[listener.Guid].Content.MEMOIRS; context.MEMOIRS.Remove(memoir.Last()); context.SaveChanges(); dictionaryAgents[listener.Guid].TotalMemoir--; listener.SendPacket((byte)TcpCommands.ServerOK, "Воспаминание удаленно."); return; } listener.SendPacket((byte)TcpCommands.ServerFailed, "Необходимо авторизоваться."); break; case (byte)TcpCommands.ClientRegistrationQuery: string login = dictionaryAgents[listener.Guid].Login; if (context.USERS.ToList().Exists(u => u.USER_LOGIN == login)) { listener.SendPacket((byte)TcpCommands.ServerRegistrationFailed, "Такой пользователь уже зарегестрирован."); return; } context.USERS.Add(new USERS { USER_LOGIN = login, USER_HASH = GetHash(AgentRelay.MakeStringFromPacketContents(packet)), REGISTRATION_DATE = DateTime.Now, USER_GUID = Guid.NewGuid() }); context.SaveChanges(); listener.SendPacket((byte)TcpCommands.ServerRegistrationOK); break; case (byte)TcpCommands.ClientBye: AgentDisconnected("Agent Disconnected! GUID -> " + listener.Guid + ", User login -> " + dictionaryAgents[listener.Guid].Login + ", Date -> " + DateTime.Now); break; } }
private void Server_OnNewAgentConnected(AgentRelay agentRelay) { agentRelay.OnNewPacketReceived += Listener_OnNewPacketReceived; }
/// <summary> /// Main server thread /// </summary> private void WorkerThread() { DateTime dtLastActivityReportSent = DateTime.Now; TimeSpan tsGuardTime = TimeSpan.FromSeconds(15); while (!m_evStop.WaitOne(500)) { lock (m_tcpListener) { if (m_AcceptIncommingConnections) { if (m_tcpListener.Pending()) { try { AgentRelay agent = AgentRelay.FromClient(m_tcpListener.AcceptTcpClient()); if (agent.IsFaulty) { agent.Disconnect(); agent = null; } else { if (OnNewAgentConnected != null) { OnNewAgentConnected(agent); } // Append it to agents list lock (m_Agents) { m_Agents.Add(agent); } } } catch (Exception ex) { if (OnServerFailedToAcceptConnection != null) { OnServerFailedToAcceptConnection(ex); } } } } } // lock // Remove Faulties 91/08/01 for (int i = 0; i < m_Agents.Count; i++) { if (m_Agents[i].IsFaulty) { m_Agents[i].Disconnect(); m_Agents[i] = null; m_Agents.RemoveAt(i); --i; } } // Report clients about us if (m_bEnableAutoHandshake && (DateTime.Now - dtLastActivityReportSent > tsGuardTime)) { for (int i = 0; i < m_Agents.Count; i++) { // It is clear, if the other side is not accessable, it will become Faulty // so there is no need to check handshake result for that. try { m_Agents[i].StartHandshakeAsync(); } catch { } } dtLastActivityReportSent = DateTime.Now; } } // Close all connections and cleanup... if (m_bAutoCleanupConnections) { lock (m_Agents) { for (int i = 0; i < m_Agents.Count; i++) { m_Agents[i].Dispose(); m_Agents[i] = null; } m_Agents.Clear(); } } }