7 #include <boost/make_shared.hpp>
8 #include <boost/foreach.hpp>
9 #include "../common/Logger.hpp"
10 #include "../common/network/Command.hpp"
11 #include "../common/network/Utils.hpp"
15 Server::Server(uint16_t port) :
16 endpoint_(tcp::v4(), port),
17 acceptor_(io_service_, endpoint_),
18 socket_udp_(io_service_, udp::endpoint(udp::v4(), port)),
20 max_total_read_average_(5000),
21 max_session_read_average_(600),
22 min_session_read_average_(100),
23 session_read_average_(200)
27 void Server::Start(CallbackFuncPtr callback)
29 callback_ = std::make_shared<CallbackFunc>(
30 [&](network::Command c){
33 if (c.header() == network::header::FatalConnectionError) {
36 auto new_average = GetSessionReadAverageLimit();
37 if (session_read_average_ != new_average) {
38 session_read_average_ = new_average;
39 SendAll(network::ClientReceiveWriteAverageLimitUpdate(session_read_average_));
44 // 通信量制限を越えていた場合、強制的に切断
45 else if (auto session = c.session().lock()) {
46 if (session->GetReadByteAverage() > session_read_average_) {
47 Logger::Info(_T("Banished session: %d"), session->id());
58 auto new_session = boost::make_shared<ServerSession>(io_service_);
59 acceptor_.async_accept(new_session->tcp_socket(),
60 boost::bind(&Server::ReceiveSession, this, new_session, boost::asio::placeholders::error));
64 socket_udp_.async_receive_from(
65 boost::asio::buffer(receive_buf_udp_, UDP_MAX_RECEIVE_LENGTH), sender_endpoint_,
66 boost::bind(&Server::ReceiveUDP, this,
67 boost::asio::placeholders::error,
68 boost::asio::placeholders::bytes_transferred));
71 boost::asio::io_service::work work(io_service_);
80 bool Server::Empty() const
82 return sessions_.size() == 0;
85 void Server::ReceiveSession(const SessionPtr& session, const boost::system::error_code& error)
87 if (session_read_average_ > min_session_read_average_) {
88 session->set_on_receive(callback_);
90 sessions_.push_back(SessionWeakPtr(session));
93 session->Send(ClientRequestedClientInfo());
96 auto new_average = GetSessionReadAverageLimit();
97 session->Send(network::ClientReceiveWriteAverageLimitUpdate(session_read_average_));
99 if (session_read_average_ != new_average) {
100 session_read_average_ = new_average;
101 SendOthers(network::ClientReceiveWriteAverageLimitUpdate(session_read_average_),
106 Logger::Info("Refuse Session");
107 session->SyncSend(ClientReceiveServerCrowdedError());
111 auto new_session = boost::make_shared<ServerSession>(io_service_);
112 acceptor_.async_accept(new_session->tcp_socket(),
113 boost::bind(&Server::ReceiveSession, this, new_session, boost::asio::placeholders::error));
116 auto it = std::remove_if(sessions_.begin(), sessions_.end(),
117 [](const SessionWeakPtr& ptr){
118 return ptr.expired();
120 sessions_.erase(it, sessions_.end());
124 void Server::SendAll(const Command& command)
126 BOOST_FOREACH(SessionWeakPtr& ptr, sessions_) {
127 if (auto session = ptr.lock()) {
128 session->Send(command);
133 void Server::SendOthers(const Command& command, SessionWeakPtr self_ptr)
135 BOOST_FOREACH(SessionWeakPtr& ptr, sessions_) {
136 if (auto session = ptr.lock()) {
137 if (auto self = self_ptr.lock()) {
138 if (*session != *self) {
139 session->Send(command);
146 void Server::SendUDPTestPacket(const std::string& ip_address, uint16_t port)
148 using boost::asio::ip::udp;
150 std::stringstream port_str;
151 port_str << (int)port;
153 udp::resolver resolver(io_service_);
154 udp::resolver::query query(udp::v4(), ip_address.c_str(), port_str.str().c_str());
155 udp::resolver::iterator iterator = resolver.resolve(query);
157 static char request[] = "MMO UDP Test Packet";
158 for (int i = 0; i < UDP_TEST_PACKET_TIME; i++) {
160 io_service_.post(boost::bind(&Server::DoWriteUDP, this, request, *iterator));
164 void Server::ReceiveUDP(const boost::system::error_code& error, size_t bytes_recvd)
166 if (bytes_recvd > 0) {
167 std::string buffer(receive_buf_udp_, bytes_recvd);
171 socket_udp_.async_receive_from(
172 boost::asio::buffer(receive_buf_udp_, UDP_MAX_RECEIVE_LENGTH), sender_endpoint_,
173 boost::bind(&Server::ReceiveUDP, this,
174 boost::asio::placeholders::error,
175 boost::asio::placeholders::bytes_transferred));
177 Logger::Error("%s", error.message());
181 void Server::DoWriteUDP(const std::string& msg, const udp::endpoint& endpoint)
183 boost::shared_ptr<std::string> s =
184 boost::make_shared<std::string>(msg.data(), msg.size());
186 socket_udp_.async_send_to(
187 boost::asio::buffer(s->data(), s->size()), endpoint,
188 boost::bind(&Server::WriteUDP, this,
189 boost::asio::placeholders::error, s));
192 void Server::WriteUDP(const boost::system::error_code& error, boost::shared_ptr<std::string> holder)
195 // if (!send_queue_.empty()) {
196 // send_queue_.pop();
197 // if (!send_queue_.empty())
199 // boost::asio::async_write(socket_tcp_,
200 // boost::asio::buffer(send_queue_.front().data(),
201 // send_queue_.front().size()),
202 // boost::bind(&Session::WriteTCP, this,
203 // boost::asio::placeholders::error));
211 Command Server::FetchUDP(const std::string& buffer)
215 header::CommandHeader header;
219 size_t readed = network::Utils::Deserialize(buffer, &user_id, &count, &header);
220 if (readed < buffer.size()) {
221 body = buffer.substr(readed);
224 return Command(header, body, session);
227 void Server::ServerSession::Start()
232 socket_tcp_.set_option(boost::asio::ip::tcp::no_delay(true));
235 global_ip_ = socket_tcp_.remote_endpoint().address().to_string();
237 boost::asio::async_read_until(socket_tcp_,
238 receive_buf_, NETWORK_UTILS_DELIMITOR,
240 &ServerSession::ReceiveTCP, shared_from_this(),
241 boost::asio::placeholders::error));
244 int Server::GetSessionReadAverageLimit()
246 int byte = max_total_read_average_ / (sessions_.size() + 1);
247 byte = std::min(byte, max_session_read_average_);
252 int Server::max_total_read_average() const
254 return max_total_read_average_;
257 int Server::max_session_read_average() const
259 return max_session_read_average_;
262 int Server::min_session_read_average() const
264 return min_session_read_average_;
267 void Server::set_max_total_read_average(int byte)
269 max_total_read_average_ = byte;
272 void Server::set_max_session_read_average(int byte)
274 max_session_read_average_ = byte;
277 void Server::set_min_session_read_average(int byte)
279 min_session_read_average_ = byte;