Network: Made send async in RoomMember
This commit is contained in:
		
							parent
							
								
									859be35d54
								
							
						
					
					
						commit
						a0626221a5
					
				@ -73,6 +73,11 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    void SendMacCollision(ENetPeer* client);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sends a ID_ROOM_VERSION_MISMATCH message telling the client that the MAC is invalid.
 | 
			
		||||
     */
 | 
			
		||||
    void SendVersionMismatch(ENetPeer* client);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Notifies the member that its connection attempt was successful,
 | 
			
		||||
     * and it is now part of the room.
 | 
			
		||||
@ -170,6 +175,9 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) {
 | 
			
		||||
    MacAddress preferred_mac;
 | 
			
		||||
    packet >> preferred_mac;
 | 
			
		||||
 | 
			
		||||
    u32 client_version;
 | 
			
		||||
    packet >> client_version;
 | 
			
		||||
 | 
			
		||||
    if (!IsValidNickname(nickname)) {
 | 
			
		||||
        SendNameCollision(event->peer);
 | 
			
		||||
        return;
 | 
			
		||||
@ -186,6 +194,11 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) {
 | 
			
		||||
        preferred_mac = GenerateMacAddress();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (client_version != network_version) {
 | 
			
		||||
        SendVersionMismatch(event->peer);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // At this point the client is ready to be added to the room.
 | 
			
		||||
    Member member{};
 | 
			
		||||
    member.mac_address = preferred_mac;
 | 
			
		||||
@ -232,6 +245,17 @@ void Room::RoomImpl::SendMacCollision(ENetPeer* client) {
 | 
			
		||||
    enet_host_flush(server);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Room::RoomImpl::SendVersionMismatch(ENetPeer* client) {
 | 
			
		||||
    Packet packet;
 | 
			
		||||
    packet << static_cast<MessageID>(IdVersionMismatch);
 | 
			
		||||
    packet << network_version;
 | 
			
		||||
 | 
			
		||||
    ENetPacket* enet_packet =
 | 
			
		||||
        enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
 | 
			
		||||
    enet_peer_send(client, 0, enet_packet);
 | 
			
		||||
    enet_host_flush(server);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Room::RoomImpl::SendJoinSuccess(ENetPeer* client, MacAddress mac_address) {
 | 
			
		||||
    Packet packet;
 | 
			
		||||
    packet << static_cast<MessageID>(IdJoinSuccess);
 | 
			
		||||
@ -291,7 +315,7 @@ void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) {
 | 
			
		||||
    if (destination_address == BroadcastMac) { // Send the data to everyone except the sender
 | 
			
		||||
        for (const auto& member : members) {
 | 
			
		||||
            if (member.peer != event->peer)
 | 
			
		||||
                enet_peer_send(member.peer, 0, event->packet);
 | 
			
		||||
                enet_peer_send(member.peer, 0, enet_packet);
 | 
			
		||||
        }
 | 
			
		||||
    } else { // Send the data only to the destination client
 | 
			
		||||
        auto member = std::find_if(members.begin(), members.end(),
 | 
			
		||||
@ -327,9 +351,9 @@ void Room::RoomImpl::HandleChatPacket(const ENetEvent* event) {
 | 
			
		||||
 | 
			
		||||
    ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(),
 | 
			
		||||
                                                 ENET_PACKET_FLAG_RELIABLE);
 | 
			
		||||
    for (auto it = members.begin(); it != members.end(); ++it) {
 | 
			
		||||
        if (it->peer != event->peer)
 | 
			
		||||
            enet_peer_send(it->peer, 0, enet_packet);
 | 
			
		||||
    for (const auto& member : members) {
 | 
			
		||||
        if (member.peer != event->peer)
 | 
			
		||||
            enet_peer_send(member.peer, 0, enet_packet);
 | 
			
		||||
    }
 | 
			
		||||
    enet_host_flush(server);
 | 
			
		||||
}
 | 
			
		||||
@ -369,6 +393,9 @@ Room::~Room() = default;
 | 
			
		||||
void Room::Create(const std::string& name, const std::string& server_address, u16 server_port) {
 | 
			
		||||
    ENetAddress address;
 | 
			
		||||
    address.host = ENET_HOST_ANY;
 | 
			
		||||
    if (!server_address.empty()) {
 | 
			
		||||
        enet_address_set_host(&address, server_address.c_str());
 | 
			
		||||
    }
 | 
			
		||||
    address.port = server_port;
 | 
			
		||||
 | 
			
		||||
    room_impl->server = enet_host_create(&address, MaxConcurrentConnections, NumChannels, 0, 0);
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,8 @@
 | 
			
		||||
 | 
			
		||||
namespace Network {
 | 
			
		||||
 | 
			
		||||
constexpr u32 network_version = 1; ///< The version of this Room and RoomMember
 | 
			
		||||
 | 
			
		||||
constexpr u16 DefaultRoomPort = 1234;
 | 
			
		||||
constexpr size_t NumChannels = 1; // Number of channels used for the connection
 | 
			
		||||
 | 
			
		||||
@ -37,7 +39,9 @@ enum RoomMessageTypes {
 | 
			
		||||
    IdWifiPacket,
 | 
			
		||||
    IdChatMessage,
 | 
			
		||||
    IdNameCollision,
 | 
			
		||||
    IdMacCollision
 | 
			
		||||
    IdMacCollision,
 | 
			
		||||
    IdVersionMismatch,
 | 
			
		||||
    IdCloseRoom
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// This is what a server [person creating a server] would use.
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
@ -33,8 +34,10 @@ public:
 | 
			
		||||
 | 
			
		||||
    std::mutex network_mutex; ///< Mutex that controls access to the `client` variable.
 | 
			
		||||
    /// Thread that receives and dispatches network packets
 | 
			
		||||
    std::unique_ptr<std::thread> receive_thread;
 | 
			
		||||
    void ReceiveLoop();
 | 
			
		||||
    std::unique_ptr<std::thread> loop_thread;
 | 
			
		||||
    std::mutex send_list_mutex;  ///< Mutex that controls access to the `send_list` variable.
 | 
			
		||||
    std::list<Packet> send_list; ///< A list that stores all packets to send the async
 | 
			
		||||
    void MemberLoop();
 | 
			
		||||
    void StartLoop();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -91,7 +94,7 @@ bool RoomMember::RoomMemberImpl::IsConnected() const {
 | 
			
		||||
    return state == State::Joining || state == State::Joined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RoomMember::RoomMemberImpl::ReceiveLoop() {
 | 
			
		||||
void RoomMember::RoomMemberImpl::MemberLoop() {
 | 
			
		||||
    // Receive packets while the connection is open
 | 
			
		||||
    while (IsConnected()) {
 | 
			
		||||
        std::lock_guard<std::mutex> lock(network_mutex);
 | 
			
		||||
@ -121,6 +124,9 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
 | 
			
		||||
                case IdMacCollision:
 | 
			
		||||
                    SetState(State::MacCollision);
 | 
			
		||||
                    break;
 | 
			
		||||
                case IdVersionMismatch:
 | 
			
		||||
                    SetState(State::WrongVersion);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
@ -128,22 +134,30 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
 | 
			
		||||
                break;
 | 
			
		||||
            case ENET_EVENT_TYPE_DISCONNECT:
 | 
			
		||||
                SetState(State::LostConnection);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            std::lock_guard<std::mutex> lock(send_list_mutex);
 | 
			
		||||
            for (const auto& packet : send_list) {
 | 
			
		||||
                ENetPacket* enetPacket = enet_packet_create(packet.GetData(), packet.GetDataSize(),
 | 
			
		||||
                                                            ENET_PACKET_FLAG_RELIABLE);
 | 
			
		||||
                enet_peer_send(server, 0, enetPacket);
 | 
			
		||||
            }
 | 
			
		||||
            enet_host_flush(client);
 | 
			
		||||
            send_list.clear();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    Disconnect();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void RoomMember::RoomMemberImpl::StartLoop() {
 | 
			
		||||
    receive_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::ReceiveLoop, this);
 | 
			
		||||
    loop_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::MemberLoop, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RoomMember::RoomMemberImpl::Send(Packet& packet) {
 | 
			
		||||
    std::lock_guard<std::mutex> lock(network_mutex);
 | 
			
		||||
    ENetPacket* enetPacket =
 | 
			
		||||
        enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
 | 
			
		||||
    enet_peer_send(server, 0, enetPacket);
 | 
			
		||||
    enet_host_flush(client);
 | 
			
		||||
    std::lock_guard<std::mutex> lock(send_list_mutex);
 | 
			
		||||
    send_list.push_back(std::move(packet));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname,
 | 
			
		||||
@ -152,6 +166,7 @@ void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname,
 | 
			
		||||
    packet << static_cast<MessageID>(IdJoinRequest);
 | 
			
		||||
    packet << nickname;
 | 
			
		||||
    packet << preferred_mac;
 | 
			
		||||
    packet << network_version;
 | 
			
		||||
    Send(packet);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -238,11 +253,9 @@ void RoomMember::RoomMemberImpl::Disconnect() {
 | 
			
		||||
    room_information.member_slots = 0;
 | 
			
		||||
    room_information.name.clear();
 | 
			
		||||
 | 
			
		||||
    if (server) {
 | 
			
		||||
        enet_peer_disconnect(server, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
    if (!server)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    enet_peer_disconnect(server, 0);
 | 
			
		||||
 | 
			
		||||
    ENetEvent event;
 | 
			
		||||
    while (enet_host_service(client, &event, ConnectionTimeoutMs) > 0) {
 | 
			
		||||
@ -296,14 +309,14 @@ RoomInformation RoomMember::GetRoomInformation() const {
 | 
			
		||||
void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port,
 | 
			
		||||
                      u16 client_port) {
 | 
			
		||||
    // If the member is connected, kill the connection first
 | 
			
		||||
    if (room_member_impl->receive_thread && room_member_impl->receive_thread->joinable()) {
 | 
			
		||||
    if (room_member_impl->loop_thread && room_member_impl->loop_thread->joinable()) {
 | 
			
		||||
        room_member_impl->SetState(State::Error);
 | 
			
		||||
        room_member_impl->receive_thread->join();
 | 
			
		||||
        room_member_impl->receive_thread.reset();
 | 
			
		||||
        room_member_impl->loop_thread->join();
 | 
			
		||||
        room_member_impl->loop_thread.reset();
 | 
			
		||||
    }
 | 
			
		||||
    // If the thread isn't running but the ptr still exists, reset it
 | 
			
		||||
    else if (room_member_impl->receive_thread) {
 | 
			
		||||
        room_member_impl->receive_thread.reset();
 | 
			
		||||
    else if (room_member_impl->loop_thread) {
 | 
			
		||||
        room_member_impl->loop_thread.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ENetAddress address{};
 | 
			
		||||
@ -361,8 +374,8 @@ void RoomMember::SendGameName(const std::string& game_name) {
 | 
			
		||||
 | 
			
		||||
void RoomMember::Leave() {
 | 
			
		||||
    room_member_impl->SetState(State::Idle);
 | 
			
		||||
    room_member_impl->receive_thread->join();
 | 
			
		||||
    room_member_impl->receive_thread.reset();
 | 
			
		||||
    room_member_impl->loop_thread->join();
 | 
			
		||||
    room_member_impl->loop_thread.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Network
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,7 @@ public:
 | 
			
		||||
        // Reasons why connection was rejected
 | 
			
		||||
        NameCollision,  ///< Somebody is already using this name
 | 
			
		||||
        MacCollision,   ///< Somebody is already using that mac-address
 | 
			
		||||
        WrongVersion,   ///< The room version is not the same as for this RoomMember
 | 
			
		||||
        CouldNotConnect ///< The room is not responding to a connection attempt
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user