public void SendPacketAll(int roomID, COMMAND command, PacketMaker packet) { if (roomDic.TryGetValue(roomID, out Room room)) { room.SendPacketAll(command, packet); } }
public void SendMsg(string msg) { PacketMaker maker = new PacketMaker(); maker.SetMsgLength(Encoding.UTF8.GetByteCount(msg)); maker.SetCommand((int)COMMAND.RECEIVE_CHAT_MSG); maker.SetStringData(msg); SendPacket(COMMAND.RECEIVE_CHAT_MSG, maker); }
public void SendPacketAll(COMMAND command, PacketMaker packet) { foreach (var user in tokenList) { //// 같으면 넘긴다 //if (user == token) // continue; user.SendPacket(command, packet); } }
// 패킷 전송 public void SendPacket(COMMAND command, PacketMaker packet) { lock (lockQueueObj) { // 큐에 데이터가 없다면 추가하고 패킷을 보내자 if (packetQueue.Count == 0) { packetQueue.Enqueue(packet); StartSend(); return; } // 큐에 데이터가 있다면 넣기만 하자 packetQueue.Enqueue(packet); } }
private void StartSend() { lock (lockQueueObj) { bool isComplete = true; // 체크를 큐가 들어있는지로 하므로 끝나기 전까지 dequeue 금지 PacketMaker maker = packetQueue.Peek(); // 데이터를 보내자 sendArgs.AcceptSocket = null; sendArgs.SetBuffer(maker.dataBuffer, 0, maker.currentPos); isComplete = socket.SendAsync(sendArgs); if (!isComplete) { SendComplete(socket, sendArgs); } } //switch (command) //{ // case COMMAND.SET_USER_ID_DONE: // sendArgs.AcceptSocket = null; // sendArgs.SetBuffer(packet.dataBuffer, 0, packet.currentPos); // socket.SendAsync(sendArgs); // break; // case COMMAND.RECEIVE_CHAT_MSG: // sendArgs.AcceptSocket = null; // sendArgs.SetBuffer(packet.dataBuffer, 0, packet.currentPos); // socket.SendAsync(sendArgs); // break; //} }
// 패킷 수신 public void ReceivePacket(COMMAND command) { switch (command) { case COMMAND.SET_USER_ID: { string msg = Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength); PacketMaker maker = new PacketMaker(); if (!userManager.FindUserID(msg)) { maker.SetMsgLength(Encoding.UTF8.GetByteCount(msg) + 4); maker.SetCommand((int)COMMAND.SET_USER_ID_DONE); maker.SetIntData(1); maker.SetStringData(msg); userID = msg; serverLogCallback(userID + "님이 접속하셨습니다."); //userManager.SendMsgAll(userID + "님이 접속하셨습니다.", this); } else { maker.SetMsgLength(Encoding.UTF8.GetByteCount("ID Already Exist") + 4); maker.SetCommand((int)COMMAND.SET_USER_ID_DONE); maker.SetIntData(0); maker.SetStringData("ID Already Exist"); } SendPacket(COMMAND.SET_USER_ID_DONE, maker); break; } case COMMAND.SEND_CHAT_MSG: { StringBuilder builder = new StringBuilder(); builder.Append(userID); builder.Append(" : "); builder.Append(Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength)); roomManager.SendMsgAll(roomID, builder.ToString(), this); receiveMessageCallback(builder.ToString()); builder.Clear(); break; } case COMMAND.SERVER_DISCONNECTED: { // 아이디로 접속을 했다면 if (!string.IsNullOrEmpty(userID)) { userManager.SendMsgAll(userID + "님이 접속을 종료하였습니다.", this); } // 해당 소켓에 대한 접속종료가 요청되었음. // UserManager에서 해당 토큰 삭제 userManager.RemoveUserToken(this); socket.Disconnect(false); // 소켓 DisConnect 후 Dispose로 다 해제 해 주자 socket.Dispose(); receiveArgs.Dispose(); sendArgs.Dispose(); socket = null; receiveArgs = null; sendArgs = null; //receiveMessageCallback(msg); break; } case COMMAND.GET_ROOM: { StringBuilder builder = new StringBuilder(); builder.Append(roomManager.GetRoomDic().Count); builder.Append("#"); foreach (var data in roomManager.GetRoomDic()) { builder.Append(data.Value.GetRoomName()); builder.Append("^"); builder.Append(data.Value.GetRoomID()); builder.Append("^"); builder.Append(data.Value.GetRoomUserList().Count); builder.Append("|"); } if (builder.Length != 0) { builder.Remove(builder.Length - 1, 1); } // 방의 수가 몇이되든 상관없으므로 패킷 생성해서 보내기 PacketMaker maker = new PacketMaker(); maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString())); maker.SetCommand((int)COMMAND.GET_ROOM_DONE); maker.SetStringData(builder.ToString()); SendPacket(COMMAND.GET_ROOM_DONE, maker); break; } case COMMAND.CREATE_ROOM: { // 방 이름 가져오기. string roomName = Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength); roomID = roomManager.CreateRoomID(); Room room = new Room(); room.SetRoomName(roomName); // 동일한 아이디의 방이 있으면 실패처리 // 여기선 간단하게 현재 카운트를 아이디로하자... // 이대로 만들면 문제가 발생할 여지가 충분하다. 중간에 방이 삭제되면 어떻게 할 것인가? if (roomManager.CheckRoomID(roomID)) { } room.SetRoomID(roomManager.GetRoomDic().Count); // 최소 방 생성자는 접속 유저이기도 하므로 room.AddUser(this); // RoomManager에 셋팅 roomManager.AddRoom(roomID, room); // 생성한 방에 대한 정보를 클라에 다시 넘겨주자 StringBuilder builder = new StringBuilder(); builder.Append(roomID); builder.Append("#"); builder.Append(roomName); builder.Append("#"); builder.Append(room.GetRoomUserList().Count); builder.Append("#"); foreach (var data in room.GetRoomUserList()) { builder.Append(data.userID); builder.Append("|"); } PacketMaker maker = new PacketMaker(); maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString())); maker.SetCommand((int)COMMAND.CREATE_ROOM_DONE); maker.SetStringData(builder.ToString()); SendPacket(COMMAND.CREATE_ROOM_DONE, maker); // 해당 유저를 제외하고 방 갱신 패킷을 보내야함 builder.Clear(); builder.Append(roomManager.GetRoomDic().Count); builder.Append("#"); foreach (var data in roomManager.GetRoomDic()) { builder.Append(data.Value.GetRoomName()); builder.Append("^"); builder.Append(data.Value.GetRoomID()); builder.Append("^"); builder.Append(data.Value.GetRoomUserList().Count); builder.Append("|"); } if (builder.Length != 0) { builder.Remove(builder.Length - 1, 1); } // 방의 수가 몇이되든 상관없으므로 패킷 생성해서 보내기 maker = new PacketMaker(); maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString())); maker.SetCommand((int)COMMAND.GET_ROOM_DONE); maker.SetStringData(builder.ToString()); userManager.SendPacketAll(COMMAND.CREATE_ROOM_DONE, maker, this); break; } case COMMAND.JOIN_ROOM: { // 접속할 룸 ID string roomName = Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength); roomID = roomManager.FindRoomID(roomName); // 클라에 실패에 대한 메세지를 보내주자 if (roomID == -1) { } Room room; // 접속할 룸을 찾아서 해당 유저를 추가한다 if (roomManager.GetRoomDic().TryGetValue(roomID, out room)) { room.AddUser(this); } StringBuilder builder = new StringBuilder(); builder.Append(userID); builder.Append("님이 접속하셨습니다."); // 접속했다고 방의 다른 클라들에 메세지 보내주자 roomManager.SendMsgAll(roomID, builder.ToString(), this); // 접속완료 메세지 보내기 builder.Clear(); builder.Append(roomID); builder.Append("#"); builder.Append(roomManager.GetRoomName(roomID)); builder.Append("#"); builder.Append(room.GetRoomUserList().Count); builder.Append("#"); foreach (var data in room.GetRoomUserList()) { builder.Append(data.userID); builder.Append("|"); } PacketMaker maker = new PacketMaker(); maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString())); maker.SetCommand((int)COMMAND.JOIN_ROOM_DONE); maker.SetStringData(builder.ToString()); roomManager.SendPacketAll(roomID, COMMAND.JOIN_ROOM_DONE, maker); break; } case COMMAND.EXIT_ROOM: { Room room; // 접속할 룸을 찾아서 해당 유저를 제거한다 if (roomManager.GetRoomDic().TryGetValue(roomID, out room)) { room.RemoveUser(this); } StringBuilder builder = new StringBuilder(); PacketMaker maker = new PacketMaker(); // 룸에 접속한 유저가 있다면 if (room.GetRoomUserList().Count != 0) { // 접속종료를 다른 클라에 보내주자 builder.Append(userID); builder.Append("님이 접속을 종료하셨습니다."); roomManager.SendMsgAll(roomID, builder.ToString(), this); // 접속이 종료되어 남은 리스트 보내주기 builder.Clear(); builder.Append(roomID); builder.Append("#"); builder.Append(roomManager.GetRoomName(roomID)); builder.Append("#"); builder.Append(room.GetRoomUserList().Count); builder.Append("#"); foreach (var data in room.GetRoomUserList()) { builder.Append(data.userID); builder.Append("|"); } maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString())); maker.SetCommand((int)COMMAND.JOIN_ROOM_DONE); maker.SetStringData(builder.ToString()); // 지금은 방에서 나간 유저에게도 보내지만 메소드를 하나 더 추가해서 자기 자신에겐 안보내는 것도 만들면 좋을듯 roomManager.SendPacketAll(roomID, COMMAND.JOIN_ROOM_DONE, maker); } // 유저가 없다면 else { // 방 목록에서 지우고 roomManager.RemoveRoom(roomID); } // 종료되었다고 알려주자 maker = new PacketMaker(); maker.SetMsgLength(BitConverter.GetBytes(1).Length); maker.SetCommand((int)COMMAND.EXIT_ROOM_DONE); maker.SetIntData(1); SendPacket(COMMAND.EXIT_ROOM_DONE, maker); break; } } }