266 lines
7.5 KiB
C++
266 lines
7.5 KiB
C++
#include "precompile.h"
|
|
|
|
#include <google/protobuf/message.h>
|
|
#include <a8/mixedsession.h>
|
|
#include <a8/tcplistener.h>
|
|
|
|
#include "GGListener.h"
|
|
|
|
#include <f8/netmsghandler.h>
|
|
#include <f8/msgqueue.h>
|
|
#include <f8/udplog.h>
|
|
|
|
#include "app.h"
|
|
#include "jsondatamgr.h"
|
|
#include "handlermgr.h"
|
|
#include "playermgr.h"
|
|
|
|
class SocketDisconnectHandler : public std::enable_shared_from_this<SocketDisconnectHandler>
|
|
{
|
|
public:
|
|
a8::CommonCbProc cb;
|
|
int socket_handle = 0;
|
|
list_head entry;
|
|
long long add_tick = 0;
|
|
std::shared_ptr<SocketDisconnectHandler> holder;
|
|
|
|
SocketDisconnectHandler()
|
|
{
|
|
}
|
|
|
|
~SocketDisconnectHandler()
|
|
{
|
|
}
|
|
|
|
};
|
|
|
|
class GCClientSession: public a8::MixedSession
|
|
{
|
|
public:
|
|
|
|
virtual void DecodeUserPacket(char* buf, int& offset, unsigned int buflen) override
|
|
{
|
|
#if 1
|
|
is_activite = true;
|
|
#endif
|
|
bool warning = false;
|
|
|
|
while (buflen - offset >= sizeof(f8::WSProxyPackHead_C)) {
|
|
f8::WSProxyPackHead_C* p = (f8::WSProxyPackHead_C*)&buf[offset];
|
|
if (p->magic_code == f8::MAGIC_CODE) {
|
|
if (buflen - offset < sizeof(f8::WSProxyPackHead_C) + p->packlen) {
|
|
break;
|
|
}
|
|
f8::App::Instance()->AddSocketMsg
|
|
(SF_GameGate,
|
|
(socket_handle << 16) + p->socket_handle,
|
|
p->ip_saddr,
|
|
p->msgid,
|
|
p->seqid,
|
|
&buf[offset + sizeof(f8::WSProxyPackHead_C)],
|
|
p->packlen,
|
|
0);
|
|
offset += sizeof(f8::WSProxyPackHead_C) + p->packlen;
|
|
} else {
|
|
warning = true;
|
|
offset++;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (warning) {
|
|
f8::UdpLog::Instance()->Warning("收到client非法数据包 buflen:%d", {buflen});
|
|
}
|
|
}
|
|
|
|
virtual void OnConnect() override
|
|
{
|
|
f8::UdpLog::Instance()->Warning("OnConnect socket_handle:%d", {socket_handle});
|
|
}
|
|
|
|
virtual void OnRawHttpGet(const std::string& url, const std::string& querystr,
|
|
std::string& response) override
|
|
{
|
|
f8::MsgQueue::Instance()->PostMsg
|
|
(IM_ExecGM,
|
|
a8::Args
|
|
(
|
|
{
|
|
socket_handle,
|
|
a8::XValue(url).GetString(),
|
|
a8::XValue(querystr).GetString(),
|
|
saddr
|
|
}
|
|
));
|
|
}
|
|
|
|
virtual void OnDisConnect() override
|
|
{
|
|
f8::UdpLog::Instance()->Warning("OnDisConnect socket_handle:%d", {socket_handle});
|
|
f8::MsgQueue::Instance()->PostMsg
|
|
(IM_ClientSocketDisconnect,
|
|
a8::Args
|
|
(
|
|
{
|
|
socket_handle
|
|
}
|
|
));
|
|
}
|
|
|
|
};
|
|
|
|
static void GSListeneron_error(a8::TcpListener*, int type, int errorid)
|
|
{
|
|
f8::UdpLog::Instance()->Debug("GGListeneron_error %d %d", {type, errorid});
|
|
f8::MsgQueue::Instance()->PostMsg
|
|
(IM_GGListenerError,
|
|
a8::Args
|
|
(
|
|
{
|
|
errorid
|
|
}
|
|
));
|
|
abort();
|
|
}
|
|
|
|
void GGListener::Init()
|
|
{
|
|
tcp_listener_ = std::make_shared<a8::TcpListener>();
|
|
tcp_listener_->RegisterSessionClass<GCClientSession>(1024 * 1024 * 10);
|
|
tcp_listener_->on_error = GSListeneron_error;
|
|
|
|
tcp_listener_->bind_address = "0.0.0.0";
|
|
tcp_listener_->bind_port = JsonDataMgr::Instance()->GetConf()->At("listen_port")->AsXValue();
|
|
tcp_listener_->Open();
|
|
|
|
f8::MsgQueue::Instance()->RegisterCallBack
|
|
(IM_GGListenerError,
|
|
[] (const a8::Args& args)
|
|
{
|
|
int error_id = args.Get<int>(0);
|
|
GGListener::Instance()->OnListenError(error_id);
|
|
});
|
|
f8::MsgQueue::Instance()->RegisterCallBack
|
|
(
|
|
IM_ClientSocketDisconnect,
|
|
[this] (const a8::Args& args)
|
|
{
|
|
int gg_socket = args.Get<int>(0);
|
|
PlayerMgr::Instance()->OnGateDisconnect(gg_socket);
|
|
{
|
|
std::vector<std::weak_ptr<SocketDisconnectHandler>> del_handlers;
|
|
for (auto& pair : disconnect_listener_hash_) {
|
|
unsigned short parent_socket_handle = (pair.first >> 16) & 0xFFFF;
|
|
if (parent_socket_handle == gg_socket) {
|
|
SocketDisconnectHandler *handle = nullptr, *tmp = nullptr;
|
|
list_for_each_entry_safe(handle, tmp, &pair.second, entry) {
|
|
del_handlers.push_back(handle->holder);
|
|
handle->cb(a8::Args({pair.first}));
|
|
}
|
|
}
|
|
}
|
|
for (auto handler : del_handlers) {
|
|
RemoveSocketDisconnectHandler(handler);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
void GGListener::UnInit()
|
|
{
|
|
tcp_listener_ = nullptr;
|
|
}
|
|
|
|
void GGListener::SendText(int sockhandle, const std::string& text)
|
|
{
|
|
tcp_listener_->SendClientMsg(sockhandle, text.data(), text.size());
|
|
}
|
|
|
|
void GGListener::ForceCloseClient(int sockhandle)
|
|
{
|
|
tcp_listener_->ForceCloseClient(sockhandle);
|
|
}
|
|
|
|
void GGListener::MarkClient(int sockhandle, bool is_active)
|
|
{
|
|
tcp_listener_->MarkClient(sockhandle, is_active);
|
|
}
|
|
|
|
long long GGListener::GetSendNodeNum()
|
|
{
|
|
return tcp_listener_->send_node_num;
|
|
}
|
|
|
|
long long GGListener::GetSentNodeNum()
|
|
{
|
|
return tcp_listener_->sent_node_num;
|
|
}
|
|
|
|
long long GGListener::GetSentBytesNum()
|
|
{
|
|
return tcp_listener_->sent_bytes_num;
|
|
}
|
|
|
|
void GGListener::OnListenError(int errorid)
|
|
{
|
|
a8::XPrintf("GGListeneron_error %d\n", {errorid});
|
|
f8::App::Instance()->Terminate();
|
|
exit(1);
|
|
}
|
|
|
|
bool GGListener::DebugNetMsg(int msg_id)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::weak_ptr<SocketDisconnectHandler> GGListener::AddSocketDisconnectListener(int socket_handle, a8::CommonCbProc cb)
|
|
{
|
|
auto itr = disconnect_listener_hash_.find(socket_handle);
|
|
if (itr == disconnect_listener_hash_.end()) {
|
|
disconnect_listener_hash_[socket_handle] = list_head();
|
|
itr = disconnect_listener_hash_.find(socket_handle);
|
|
INIT_LIST_HEAD(&itr->second);
|
|
}
|
|
auto p = std::make_shared<SocketDisconnectHandler>();
|
|
p->socket_handle = socket_handle;
|
|
p->cb = cb;
|
|
p->add_tick = a8::XGetTickCount();
|
|
list_add_tail(&p->entry, &itr->second);
|
|
p->holder = p;
|
|
return p;
|
|
}
|
|
|
|
void GGListener::RemoveSocketDisconnectHandler(std::weak_ptr<SocketDisconnectHandler> handler)
|
|
{
|
|
if (!handler.expired()) {
|
|
auto p = handler.lock();
|
|
p->cb = nullptr;
|
|
p->holder = nullptr;
|
|
#if 1
|
|
f8::UdpLog::Instance()->Warning("RemoveSocketDisconnectHandler socket_handle:%d time:%d",
|
|
{
|
|
p->socket_handle,
|
|
a8::XGetTickCount() - p->add_tick
|
|
});
|
|
#endif
|
|
list_del_init(&p->entry);
|
|
}
|
|
}
|
|
|
|
void GGListener::OnClientDisconnect(int socket_handle)
|
|
{
|
|
auto itr = disconnect_listener_hash_.find(socket_handle);
|
|
if (itr != disconnect_listener_hash_.end()) {
|
|
std::vector<std::weak_ptr<SocketDisconnectHandler>> del_handlers;
|
|
SocketDisconnectHandler *handle = nullptr, *tmp = nullptr;
|
|
list_for_each_entry_safe(handle, tmp, &itr->second, entry) {
|
|
del_handlers.push_back(handle->holder);
|
|
handle->cb(a8::Args({itr->first}));
|
|
}
|
|
for (auto handler : del_handlers) {
|
|
RemoveSocketDisconnectHandler(handler);
|
|
}
|
|
}
|
|
PlayerMgr::Instance()->OnClientDisconnect(socket_handle);
|
|
}
|