mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Redid background task interface, used it to async send client packets
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "daybreak_connection.h"
|
||||
#include "../event/event_loop.h"
|
||||
#include "../event/task.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../data_verification.h"
|
||||
#include "crc32.h"
|
||||
@@ -1045,10 +1046,6 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
resends++;
|
||||
}
|
||||
}
|
||||
|
||||
if (resends >= m_owner->m_options.resends_per_connection_cycle) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1185,80 +1182,95 @@ void EQ::Net::DaybreakConnection::SendKeepAlive()
|
||||
void EQ::Net::DaybreakConnection::InternalSend(Packet &p)
|
||||
{
|
||||
m_last_send = Clock::now();
|
||||
|
||||
auto send_func = [](uv_udp_send_t* req, int status) {
|
||||
delete[](char*)req->data;
|
||||
delete req;
|
||||
};
|
||||
|
||||
|
||||
if (PacketCanBeEncoded(p)) {
|
||||
DynamicPacket out;
|
||||
out.PutPacket(0, p);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeCompression:
|
||||
if(out.GetInt8(0) == 0)
|
||||
Compress(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
||||
else
|
||||
Compress(out, 1, out.Length() - 1);
|
||||
break;
|
||||
case EncodeXOR:
|
||||
if (out.GetInt8(0) == 0)
|
||||
Encode(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
||||
else
|
||||
Encode(out, 1, out.Length() - 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
DynamicPacket *out = new DynamicPacket();
|
||||
out->PutPacket(0, p);
|
||||
|
||||
auto sp = shared_from_this();
|
||||
EQ::Task([sp, out](EQ::Task::ResolveFn resolve, EQ::Task::RejectFn reject) {
|
||||
|
||||
auto encode_passes = sp->GetEncodePasses();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
switch (encode_passes[i]) {
|
||||
case EncodeCompression:
|
||||
if(out->GetInt8(0) == 0)
|
||||
sp->Compress(*out, DaybreakHeader::size(), out->Length() - DaybreakHeader::size());
|
||||
else
|
||||
sp->Compress(*out, 1, out->Length() - 1);
|
||||
break;
|
||||
case EncodeXOR:
|
||||
if (out->GetInt8(0) == 0)
|
||||
sp->Encode(*out, DaybreakHeader::size(), out->Length() - DaybreakHeader::size());
|
||||
else
|
||||
sp->Encode(*out, 1, out->Length() - 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AppendCRC(out);
|
||||
|
||||
|
||||
sp->AppendCRC(*out);
|
||||
resolve(out);
|
||||
})
|
||||
.Then([sp, out, send_func](const EQEmu::Any &result) {
|
||||
uv_udp_send_t *send_req = new uv_udp_send_t;
|
||||
memset(send_req, 0, sizeof(*send_req));
|
||||
sockaddr_in send_addr;
|
||||
uv_ip4_addr(sp->RemoteEndpoint().c_str(), sp->RemotePort(), &send_addr);
|
||||
uv_buf_t send_buffers[1];
|
||||
|
||||
char *data = new char[out->Length()];
|
||||
memcpy(data, out->Data(), out->Length());
|
||||
send_buffers[0] = uv_buf_init(data, out->Length());
|
||||
send_req->data = send_buffers[0].base;
|
||||
|
||||
auto &stats = sp->GetStats();
|
||||
|
||||
stats.sent_bytes += out->Length();
|
||||
stats.sent_packets++;
|
||||
|
||||
auto owner = sp->GetManager();
|
||||
|
||||
if (owner->m_options.simulated_out_packet_loss && owner->m_options.simulated_out_packet_loss >= owner->m_rand.Int(0, 100)) {
|
||||
delete[](char*)send_req->data;
|
||||
delete send_req;
|
||||
return;
|
||||
}
|
||||
|
||||
uv_udp_send(send_req, &owner->m_socket, send_buffers, 1, (sockaddr*)&send_addr, send_func);
|
||||
})
|
||||
.Finally([out]() {
|
||||
delete out;
|
||||
})
|
||||
.Run();
|
||||
}
|
||||
else {
|
||||
uv_udp_send_t *send_req = new uv_udp_send_t;
|
||||
memset(send_req, 0, sizeof(*send_req));
|
||||
sockaddr_in send_addr;
|
||||
uv_ip4_addr(m_endpoint.c_str(), m_port, &send_addr);
|
||||
uv_buf_t send_buffers[1];
|
||||
|
||||
char *data = new char[out.Length()];
|
||||
memcpy(data, out.Data(), out.Length());
|
||||
send_buffers[0] = uv_buf_init(data, out.Length());
|
||||
|
||||
char *data = new char[p.Length()];
|
||||
memcpy(data, p.Data(), p.Length());
|
||||
send_buffers[0] = uv_buf_init(data, p.Length());
|
||||
send_req->data = send_buffers[0].base;
|
||||
|
||||
m_stats.sent_bytes += out.Length();
|
||||
|
||||
m_stats.sent_bytes += p.Length();
|
||||
m_stats.sent_packets++;
|
||||
|
||||
if (m_owner->m_options.simulated_out_packet_loss && m_owner->m_options.simulated_out_packet_loss >= m_owner->m_rand.Int(0, 100)) {
|
||||
delete[](char*)send_req->data;
|
||||
delete send_req;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uv_udp_send(send_req, &m_owner->m_socket, send_buffers, 1, (sockaddr*)&send_addr, send_func);
|
||||
return;
|
||||
}
|
||||
|
||||
uv_udp_send_t *send_req = new uv_udp_send_t;
|
||||
sockaddr_in send_addr;
|
||||
uv_ip4_addr(m_endpoint.c_str(), m_port, &send_addr);
|
||||
uv_buf_t send_buffers[1];
|
||||
|
||||
char *data = new char[p.Length()];
|
||||
memcpy(data, p.Data(), p.Length());
|
||||
send_buffers[0] = uv_buf_init(data, p.Length());
|
||||
send_req->data = send_buffers[0].base;
|
||||
|
||||
m_stats.sent_bytes += p.Length();
|
||||
m_stats.sent_packets++;
|
||||
|
||||
if (m_owner->m_options.simulated_out_packet_loss && m_owner->m_options.simulated_out_packet_loss >= m_owner->m_rand.Int(0, 100)) {
|
||||
delete[](char*)send_req->data;
|
||||
delete send_req;
|
||||
return;
|
||||
}
|
||||
|
||||
uv_udp_send(send_req, &m_owner->m_socket, send_buffers, 1, (sockaddr*)&send_addr, send_func);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace EQ
|
||||
|
||||
class DaybreakConnectionManager;
|
||||
class DaybreakConnection;
|
||||
class DaybreakConnection
|
||||
class DaybreakConnection : public std::enable_shared_from_this<DaybreakConnection>
|
||||
{
|
||||
public:
|
||||
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
|
||||
@@ -109,10 +109,16 @@ namespace EQ
|
||||
void QueuePacket(Packet &p);
|
||||
void QueuePacket(Packet &p, int stream);
|
||||
void QueuePacket(Packet &p, int stream, bool reliable);
|
||||
|
||||
const DaybreakConnectionStats& GetStats() const { return m_stats; }
|
||||
DaybreakConnectionStats &GetStats() { return m_stats; }
|
||||
void ResetStats();
|
||||
size_t GetRollingPing() const { return m_rolling_ping; }
|
||||
DbProtocolStatus GetStatus() { return m_status; }
|
||||
DbProtocolStatus GetStatus() const { return m_status; }
|
||||
|
||||
const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||
const DaybreakConnectionManager* GetManager() const { return m_owner; }
|
||||
DaybreakConnectionManager* GetManager() { return m_owner; }
|
||||
private:
|
||||
DaybreakConnectionManager *m_owner;
|
||||
std::string m_endpoint;
|
||||
@@ -209,7 +215,6 @@ namespace EQ
|
||||
resend_delay_factor = 1.25;
|
||||
resend_delay_min = 150;
|
||||
resend_delay_max = 5000;
|
||||
resends_per_connection_cycle = 10;
|
||||
connect_delay_ms = 500;
|
||||
stale_connection_ms = 90000;
|
||||
connect_stale_ms = 5000;
|
||||
@@ -234,7 +239,6 @@ namespace EQ
|
||||
size_t resend_delay_ms;
|
||||
size_t resend_delay_min;
|
||||
size_t resend_delay_max;
|
||||
int resends_per_connection_cycle;
|
||||
size_t connect_delay_ms;
|
||||
size_t connect_stale_ms;
|
||||
size_t stale_connection_ms;
|
||||
|
||||
Reference in New Issue
Block a user