/// <summary> /// return username list /// </summary> public static string[] GetUsers(TcpMessage Answer) { if (Answer.Msg == null) { return(null); } string usernames = Answer.Encoding.GetString(Answer.Msg); return(usernames.Split(";".ToArray(), StringSplitOptions.RemoveEmptyEntries)); }
/// <summary> /// Send single request /// </summary> /// <param name="receiver"></param> /// <param name="answer"></param> public void SendAnswer(Socket Receiver, TcpMessage Request) { this.TrySend( Request.GetBytes(), (bytesSended) => { Receiver.Disconnect(false); Receiver.Close(); }); }
public static IPEndPoint GetRemotePoint(TcpMessage Message) { try { string msg = Message.GetMessageString(); GroupCollection gs = Regex.Match(msg, @"\[([^\[\]]*)\]:([0-9]+)").Groups; string ip = gs[1].Value; string port = gs[2].Value; return(new IPEndPoint(IPAddress.Parse(ip), Int32.Parse(port))); } catch { return(null); } }
/// <summary> /// User was requested a userlist /// </summary> /// <param name="request"></param> /// <param name="endPoint"></param> public void HUserList(TcpMessage request) { IPEndPoint ep = Users[request.From].EndPoint; string usr = Users.GetKey(ep); Users[usr].Update(); SendRequest(ep, new ResponseUserList(Users.Keys).GetBytes()); Msg("User " + usr + " request a user list"); }
/// <summary> /// return username list /// </summary> public static string[] GetUsers(TcpMessage Answer) { if (Answer.Msg == null) return null; string usernames = Answer.Encoding.GetString(Answer.Msg); return usernames.Split(";".ToArray(), StringSplitOptions.RemoveEmptyEntries); }
/// <summary> /// Remote companion answer to talk offer /// </summary> void HTalkState(TcpMessage request) { int State = request.State; string translate = ResponseTalkState.TalkStateString((TalkState)State); Msg(String.Format("Talk status with {0} is {1}", request.From, translate)); if (OnTalkState != null) OnTalkState(request.From, (TalkState)State); }
/// <summary> /// Get the user list from server /// </summary> /// <param name="request"></param> void HUserList(TcpMessage Request) { Msg("Get users list"); if (OnUserList != null) OnUserList(ResponseUserList.GetUsers(Request)); }
void HServerInfo(TcpMessage Request) { Msg("Server: " + Request.GetMessageString()); }
void HTalkEnd(TcpMessage Request) { if (OnTalkEnd != null) OnTalkEnd(Request.From); Msg(Request.From + " is hang up"); }
/// <summary> /// Server send some custom data /// </summary> public void HRequestCustomData(TcpMessage request) { Msg("Receive custom data"); if (OnCustomData != null) OnCustomData((CustomData)request.State, request.GetMessageString()); }
/// <summary> /// Decrypting a request and create right responses /// </summary> private void Decrypt(TcpMessage Request) { switch ((CodeMessage)Request.Code) { case CodeMessage.AConnect: HConnect(Request); break; case CodeMessage.AUser: HUser(Request); break; case CodeMessage.AUserList: HUserList(Request); break; case CodeMessage.CWriteFor: HWriteFor(Request); break; case CodeMessage.AServerState: HServerState(Request); break; case CodeMessage.CATalkOffer: HTalkOffer(Request); break; case CodeMessage.CATalkAnswer: HTalkState(Request); break; case CodeMessage.CARequestCustomData: HRequestCustomData(Request); break; case CodeMessage.CTalkEnd: HTalkEnd(Request); break; case CodeMessage.AServerInfo: HServerInfo(Request); break; default: Msg("Unrecognized/wrong data"); break; } }
/// <summary> /// Offer to talk /// </summary> public void HTalkOffer(TcpMessage Request) { if (!Users.ContainsKey(Request.To)) { // This user is unavailable, and sender should remove this name from his userlist SendRequest(Users[Request.From].EndPoint, new ResponseUser(Request.To, UserState.UserLogOut).GetBytes()); } IPEndPoint receiver = Users[Request.To].EndPoint; SendRequest(receiver, Request.GetBytes()); IPEndPoint sender = Users[Request.From].EndPoint; SendRequest(sender, new ResponseServerInfo("Talk offer with " + Request.To + " is processing").GetBytes()); }
/// <summary> /// User request to end current talk /// </summary> public void HTalkEnd(TcpMessage Request) { if (OnTalkOccur != null) OnTalkOccur(false, Request.From, Request.To); IPEndPoint sender = Users[Request.From].EndPoint; IPEndPoint receiver = Users[Request.To].EndPoint; SendRequest(receiver, Request.GetBytes()); SendRequest(sender, new ResponseServerInfo("Talk end OK").GetBytes()); }
/// <summary> /// User request some custom data, e.g. udp server port /// </summary> public void HRequestCustomData(TcpMessage Request) { CCommon.CustomData cData = (CCommon.CustomData)Request.State; if (!CustomData.ContainsKey(cData)) return; SendRequest(Users[Request.From].EndPoint, new RequestCustomData(Request.From, cData, CustomData[cData]).GetBytes()); }
/// <summary> /// User was gently logged off /// </summary> public void HQuit(TcpMessage Request) { IPEndPoint ep = Users[Request.From].EndPoint; string deleted = Users.GetKey(ep); if (deleted == null) return; Users.Remove(deleted); SendBroadcast(new ResponseUser(deleted, UserState.UserLogOut)); Msg("User " + deleted + " was logged off"); if(OnUserState != null) OnUserState(Request.From, UserState.UserLogOut); // I'll try to send it, but he is offline... IPEndPoint sender = Users[Request.From].EndPoint; SendRequest(sender, new ResponseServerInfo("Quit OK").GetBytes()); }
/// <summary> /// User was connected /// </summary> public void HConnect(TcpMessage request) { string name = request.From; IPEndPoint tcpEP = null, udpEP = null; try { tcpEP = RequestConnect.GetRemotePoint(request); udpEP = RequestConnect.GetUdpRemotePoint(request); } catch { Msg("Wrong message format"); // Cannot answer to client because info about listener's socket is broken return; } // We should check if he in client list (it will be an error) if (Users.ContainsValue(tcpEP)) { string realName = Users.GetKey(tcpEP); string cause = "Connection: user " + name + " already connected as " + realName; SendRequest(tcpEP, new ResponseConnect(false, cause).GetBytes()); Msg(cause); return; } // and has unique name (answer Cancel) if (Users.ContainsKey(name)) { string cause = "Connection: username " + name + " is not available"; SendRequest(tcpEP, new ResponseConnect(false, cause).GetBytes()); Msg(cause); return; } SendRequest(tcpEP, new ResponseConnect(true, "OK").GetBytes()); Users.Add(name, new UserInfo(tcpEP, udpEP.Port)); Msg("User " + name + " [" + tcpEP.ToString() + "] added in user list"); if (OnUserState != null) OnUserState(name, UserState.UserLogIn); SendBroadcast(new ResponseUser(name, UserState.UserLogIn)); }
void ClientListener_OnConnect(IPEndPoint Client, byte[] Data) { try { TcpMessage header = new TcpMessage(Data); Decrypt(header); } catch (Exception e) { Msg("Cannot read data: " + e.Message); } }
/// <summary> /// Handler for write message event /// </summary> public void HWriteFor(TcpMessage Request) { IPEndPoint ep = Users[Request.From].EndPoint; Users[Request.From].Update(); // if receiver is not valid if (!Users.ContainsKey(Request.To)) { SendRequest(ep, new ResponseUser(Request.To, UserState.UserLogOut).GetBytes()); Msg("Message resend: Receiver " + Request.To + " is not valid"); return; } IPEndPoint receiver = Users[Request.To].EndPoint; string user = Users.GetKey(ep); SendRequest(receiver, new RequestTextMessage(user, Request.To, Request.GetMessageString()).GetBytes()); Msg("Message resend: from " + Request.From + " to " + Request.To); IPEndPoint sender = Users[Request.From].EndPoint; SendRequest(sender, new ResponseServerInfo("Message to " + Request.To + " OK").GetBytes()); }
/// <summary> /// Connection state /// </summary> /// <param name="request"></param> void HConnect(TcpMessage Request) { TryConnected = true; if (Request.State != 0) { Msg("Connect state OK"); if (OnConnectState != null) OnConnectState(true, ""); } else { string cause = Request.GetMessageString(); Msg("Connect state failed because " + cause); if (OnConnectState != null) OnConnectState(false, cause); } }
/// <summary> /// Send broadcast answers to all users /// </summary> /// <param name="resp"></param> public void SendBroadcast(TcpMessage resp) { foreach (var User in Users) SendRequest(User.Value.EndPoint, resp.GetBytes()); }
void HServerState(TcpMessage Request) { if (Request.State == 0) Msg("Server is closing (" + Request.GetMessageString() + ")"); else Msg("Server is on (" + Request.GetMessageString() + ")"); OnServerChangeState(Request.State != 0, Request.GetMessageString()); }
/// <summary> /// Decrypting a request and create right responses /// </summary> /// <param name="request"></param> /// <param name="endPoint"></param> private void Decrypt(TcpMessage request, IPEndPoint receiver) { /* * * * If request handler call "SendAnswer" before quit, it's OK * * * */ /* Otherwise socket should be disconnected and closed in handler directly */ if ((CodeMessage)request.Code == CodeMessage.CConnect) { HConnect(request); return; } if (!Users.ContainsKey(request.From)) { Msg("Message from unknown source: [" + receiver.ToString() + "]"); return; } receiver = Users[request.From].EndPoint; switch ((CodeMessage)request.Code) { case CodeMessage.CQuit: HQuit(request); break; case CodeMessage.CUserList: HUserList(request); break; case CodeMessage.CWriteFor: HWriteFor(request); break; case CodeMessage.CATalkOffer: HTalkOffer(request); break; case CodeMessage.CTalkEnd: HTalkEnd(request); break; case CodeMessage.CATalkAnswer: HTalkAnswer(request); break; case CodeMessage.CARequestCustomData: HRequestCustomData(request); break; default: break; } }
void HTalkOffer(TcpMessage request) { Msg(request.From + " offer to talk"); if (OnTalkOffer != null) OnTalkOffer(request.From); }
/// <summary> /// Transact talk answer message and begins the udp connection if required /// </summary> private void HTalkAnswer(TcpMessage Request) { if ((TalkState)Request.State == TalkState.Adopt) { if (OnTalkOccur != null) OnTalkOccur(true, Request.From, Request.To); } IPEndPoint receiver = Users[Request.To].EndPoint; SendRequest(receiver, Request.GetBytes()); IPEndPoint sender = Users[Request.From].EndPoint; SendRequest(sender, new ResponseServerInfo("Talk answer with " + Request.To + " OK").GetBytes()); }
/// <summary> /// Some user change his state /// </summary> /// <param name="request"></param> void HUser(TcpMessage Request) { string translate = ResponseUser.UserStateString((UserState)Request.State); Msg("User " + Request.From + " has " + translate + " state now"); if (OnUser != null) OnUser((UserState)Request.State, Request.From); }
void ServerListener_OnConnect(IPEndPoint client, byte[] data) { try { TcpMessage header = new TcpMessage(data); Decrypt(header, client); } catch (Exception e) { Msg("Cannot read data from [" + client.ToString() + "]: " + e.Message); } }
/// <summary> /// Text message event /// </summary> /// <param name="request"></param> void HWriteFor(TcpMessage Request) { Msg("Get message from " + Request.From); if (OnChat != null) OnChat(Request.From, Request.GetMessageString()); }
public static IPEndPoint GetUdpRemotePoint(TcpMessage Message) { try { string msg = Message.GetMessageString(); GroupCollection gs = Regex.Match(msg, @"\[([^\[\]]*)\]:[0-9]+[\s]([0-9]+)").Groups; string ip = gs[1].Value; string port = gs[2].Value; return new IPEndPoint(IPAddress.Parse(ip), Int32.Parse(port)); } catch { return null; } }