private void DisconnectFrom(string name) { try { Client c; if ((c = clients.WithName(name)) != null) { c.Send(new IM_Message("SERVER", String.Empty, IM_Message.MESSAGE_TYPE_SERVER_DISCONNECTING, String.Empty)); c.tcp.Close(); clients.Remove(c); LoadListToBox(); } ClientUpdateStruct custruct = new ClientUpdateStruct { name = name, type = IM_Message.MESSAGE_TYPE_CLIENT_DISCONNECTED }; //Send a CLIENT DISCONNECTED message to all clients new Thread(new ParameterizedThreadStart(SendClientListUpdateToAll)).Start(custruct); SetText(name + " disconnected"); } catch (Exception e) { MessageBox.Show(e.Message); } }
private void SendClientListUpdateToAll(object custruct) { ClientUpdateStruct cu_struct = (ClientUpdateStruct)custruct; IM_Message message = null; switch (cu_struct.type) { case IM_Message.MESSAGE_TYPE_CLIENT_CONNECTED: message = new IM_Message("SERVER", String.Empty, IM_Message.MESSAGE_TYPE_CLIENT_CONNECTED, cu_struct.name); break; case IM_Message.MESSAGE_TYPE_CLIENT_DISCONNECTED: message = new IM_Message("SERVER", String.Empty, IM_Message.MESSAGE_TYPE_CLIENT_DISCONNECTED, cu_struct.name); break; case IM_Message.MESSAGE_TYPE_CLIENT_NAME_CHANGE: //Message will be intercepted so that it's not sent to the client in the TO field //NAME_CHANGE messages will not be forwarded message = new IM_Message(cu_struct.name, String.Empty, IM_Message.MESSAGE_TYPE_CLIENT_NAME_CHANGE, cu_struct.extra); break; default: break; } Monitor.Enter(ListLock); List <Client> buffer = new List <Client>( clients.Cast <Client>() /*.Where(x => !x.Name.StartsWith("_|___|__|___|_"))*/ ); //don't want to include temporary names foreach (Client c in buffer) { if (cu_struct.name != c.Name) { //Set the TO field here message.To = c.Name; Thread.Sleep(500); c.Send(message); } } Monitor.Exit(ListLock); }
/*******************************************************************/ /// <summary> /// Brain of Server /// </summary> /// <param name="message"></param> private void ProcessReceivedMessages(object msg) { IM_Message message = (IM_Message)msg; Client sender = clients.WithName(message.From); Client receiver = clients.WithName(message.To); //if (sender == null || receiver == null) return; //SetText("Message Received from " + message.From + ": " + message.Msg); switch (message.Type) { case IM_Message.MESSAGE_TYPE_SETNAME: //Client will not use the name requested until the server has confirmed they can int type; //check to see if requested name is available if (clients.WithName(message) == null || ((string)message == String.Empty)) { SetText(sender.Name + ": SetName: '" + message + "' approved"); type = IM_Message.MESSAGE_TYPE_SETNAME_CONFIRMATION_OK; sender.Send(new IM_Message("SERVER", String.Empty, type, message.Data)); //Thread.Sleep(1000); //slow things down SynchronizeClient(message.From, message); } else { type = IM_Message.MESSAGE_TYPE_SETNAME_CONFIRMATION_NO; sender.Send(new IM_Message("SERVER", String.Empty, type, message.Data)); SetText(sender.Name + ": SetName: '" + message + "' REJECTED"); } //Send back name confirmation to Client break; case IM_Message.MESSAGE_TYPE_CLIENT_LIST_CONFIRMATION: ClientUpdateStruct custruct = new ClientUpdateStruct { name = sender.Name, type = IM_Message.MESSAGE_TYPE_CLIENT_CONNECTED }; //Send an update to the other clients Thread t2 = new Thread(new ParameterizedThreadStart(SendClientListUpdateToAll)); t2.Start(custruct); LoadListToBox(); SetText(String.Format("{0} connected", sender.Name)); break; case IM_Message.MESSAGE_TYPE_MSG: receiver.Send(new IM_Message(sender.Name, receiver.Name, IM_Message.MESSAGE_TYPE_MSG, message.Data)); break; case IM_Message.MESSAGE_TYPE_CLIENT_SHUTTING_DOWN: DisconnectFrom(message.From); break; default: break; } }