-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathKcp.h
170 lines (157 loc) · 4.37 KB
/
Kcp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#ifndef ___NICE_KCPSERVER____
#define ___NICE_KCPSERVER____
#include <string>
#include "Type.h"
#include <memory>
#include "Server.h"
#include <unordered_map>
#include <array>
#include <list>
#include <atomic>
#include "Message.h"
#include "NoCopy.h"
#include <functional>
#include "CopyablePtr.hpp"
#include "Task.hpp"
namespace nicehero
{
const i32 IKCP_OVERHEAD = 89;
const i32 INVALID_CONV = (~0);
class KcpSession;
using kcpuid = std::string;
using KcpTask = Task<bool,TO_MAIN>;
using KcpSessionPtr = std::shared_ptr<KcpSession>;
using MessagePtr = CopyablePtr<Message>;
using kcpcommand = KcpTask(*)(KcpSessionPtr, MessagePtr);
class KcpServer;
class KcpSessionImpl;
class KcpServerImpl;
class KcpMessageParser
{
public:
kcpcommand m_commands[65536] = {nullptr};
};
class KcpSessionCommand
{
public:
KcpSessionCommand(const std::type_info & info,
ui16 command,
kcpcommand fucnc
);
};
class KcpSession
:public NoCopy,public std::enable_shared_from_this<KcpSession>
{
friend class KcpSessionImpl;
friend class KcpSessionS;
friend class KcpServer;
friend class KcpServerImpl;
public:
KcpSession();
virtual void init();
virtual void init(KcpServer& server);
virtual void init2(KcpServer& server);
virtual void init3(KcpServer& server);
virtual void close();
virtual void setMessageParser(KcpMessageParser* messageParser);
virtual void sendMessage(Message& msg,bool pureUdp = false);
virtual void sendMessage(Serializable& msg, bool pureUdp = false);
KcpMessageParser* m_MessageParser = nullptr;
kcpuid& getUid();
protected:
void init_kcp();
std::unique_ptr<KcpSessionImpl> m_impl;
std::string m_hash;
kcpuid m_uid;
ui32 m_conv = INVALID_CONV;
ui64 m_serialID;
Message m_PreMsg;
bool parseMsg(unsigned char* data, ui32 len);
virtual void removeSelf();
virtual void removeSelfImpl();
void doPing();
virtual void doRead();
void doSend(Message& msg, bool pureUdp);
std::atomic_bool m_IsSending;
std::list<Message> m_SendList;
virtual void handleMessage(MessagePtr msg);
bool m_Ready = true;
std::atomic_bool m_closed;
private:
ui64 m_lastPingTime = 0;
ui64 m_lastPongTime = 0;
};
class KcpSessionS
:public KcpSession
{
friend class KcpServer;
friend class KcpSessionImpl;
friend class KcpServerImpl;
public:
KcpSessionS();
virtual ~KcpSessionS();
void init(KcpServer& server);
void init2(KcpServer& server);
void init3(KcpServer& server);
void close();
protected:
KcpServer* m_KcpServer = nullptr;
void removeSelf();
void removeSelfImpl();
void doRead()final;
private:
std::atomic_bool m_waitRemove;
};
class KcpSessionC
:public KcpSession,public Server
{
public:
KcpSessionC();
virtual ~KcpSessionC();
bool connect(const std::string& ip, ui16 port);
void init(bool isAsync = false);
void startRead();
std::atomic<bool> m_isInit;
protected:
void doRead()final;
void removeSelf();
private:
int checkServerSign(ui8* data_);//return 0 ok 1 error 2 warning
std::shared_ptr<std::string> m_buffer;
void startRead2();
std::atomic<bool> m_isStartRead2;
};
class KcpServer
:public Server
{
friend class KcpSession;
friend class KcpSessionS;
public:
KcpServer(const std::string& ip,ui16 port );
virtual ~KcpServer();
std::unique_ptr<KcpServerImpl> m_impl;
bool m_Started = false;
virtual KcpSessionS* createSession();
virtual void addSession(const kcpuid& uid, KcpSessionPtr session);
virtual void removeSession(const kcpuid& uid,ui64 serialID);
virtual void accept();
std::unordered_map<kcpuid, std::shared_ptr<KcpSession> > m_sessions;
ui32 getFreeUid();
ui32 m_maxSessions = 10000;
ui32 m_nextConv = 1;
};
KcpMessageParser& getKcpMessagerParse(const std::type_info& typeInfo);
inline KcpSessionCommand::KcpSessionCommand(const std::type_info & info, ui16 command, kcpcommand func )
{
KcpMessageParser& msgParser = getKcpMessagerParse(info);
msgParser.m_commands[command] = func;
}
}
#define KCP_SESSION_COMMAND(CLASS,COMMAND) \
static nicehero::KcpTask _##CLASS##_##COMMAND##FUNC(nicehero::KcpSessionPtr session,nicehero::MessagePtr msg); \
static nicehero::KcpSessionCommand _##CLASS##_##COMMAND(typeid(CLASS), COMMAND, _##CLASS##_##COMMAND##FUNC);\
static nicehero::KcpTask _##CLASS##_##COMMAND##FUNC(nicehero::KcpSessionPtr session,nicehero::MessagePtr msg)
#ifndef SESSION_COMMAND
#define SESSION_COMMAND KCP_SESSION_COMMAND
#endif
#endif