复现已有算法
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
*
|
||||
* @file WebSocketConnectionImpl.h
|
||||
* @author An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "impl_forwards.h"
|
||||
#include <drogon/WebSocketConnection.h>
|
||||
#include <json/value.h>
|
||||
#include <string_view>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
class WebSocketConnectionImpl;
|
||||
using WebSocketConnectionImplPtr = std::shared_ptr<WebSocketConnectionImpl>;
|
||||
|
||||
class WebSocketMessageParser
|
||||
{
|
||||
public:
|
||||
bool parse(trantor::MsgBuffer *buffer);
|
||||
|
||||
bool gotAll(std::string &message, WebSocketMessageType &type)
|
||||
{
|
||||
assert(message.empty());
|
||||
if (!gotAll_)
|
||||
return false;
|
||||
message.swap(message_);
|
||||
type = type_;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string message_;
|
||||
WebSocketMessageType type_;
|
||||
bool gotAll_{false};
|
||||
};
|
||||
|
||||
class WebSocketConnectionImpl final
|
||||
: public WebSocketConnection,
|
||||
public std::enable_shared_from_this<WebSocketConnectionImpl>,
|
||||
public trantor::NonCopyable
|
||||
{
|
||||
public:
|
||||
explicit WebSocketConnectionImpl(const trantor::TcpConnectionPtr &conn,
|
||||
bool isServer = true);
|
||||
|
||||
~WebSocketConnectionImpl() override;
|
||||
void send(
|
||||
const char *msg,
|
||||
uint64_t len,
|
||||
const WebSocketMessageType type = WebSocketMessageType::Text) override;
|
||||
void send(
|
||||
std::string_view msg,
|
||||
const WebSocketMessageType type = WebSocketMessageType::Text) override;
|
||||
void sendJson(
|
||||
const Json::Value &json,
|
||||
const WebSocketMessageType type = WebSocketMessageType::Text) override;
|
||||
|
||||
const trantor::InetAddress &localAddr() const override;
|
||||
const trantor::InetAddress &peerAddr() const override;
|
||||
|
||||
bool connected() const override;
|
||||
bool disconnected() const override;
|
||||
|
||||
void shutdown(const CloseCode code = CloseCode::kNormalClosure,
|
||||
const std::string &reason = "") override; // close write
|
||||
void forceClose() override; // close
|
||||
|
||||
void setPingMessage(const std::string &message,
|
||||
const std::chrono::duration<double> &interval) override;
|
||||
|
||||
void disablePing() override;
|
||||
|
||||
void setMessageCallback(
|
||||
const std::function<void(std::string &&,
|
||||
const WebSocketConnectionImplPtr &,
|
||||
const WebSocketMessageType &)> &callback)
|
||||
{
|
||||
messageCallback_ = callback;
|
||||
}
|
||||
|
||||
void setCloseCallback(
|
||||
const std::function<void(const WebSocketConnectionImplPtr &)> &callback)
|
||||
{
|
||||
closeCallback_ = callback;
|
||||
}
|
||||
|
||||
void onNewMessage(const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *buffer);
|
||||
|
||||
void onClose()
|
||||
{
|
||||
if (pingTimerId_ != trantor::InvalidTimerId)
|
||||
tcpConnectionPtr_->getLoop()->invalidateTimer(pingTimerId_);
|
||||
closeCallback_(shared_from_this());
|
||||
}
|
||||
|
||||
private:
|
||||
trantor::TcpConnectionPtr tcpConnectionPtr_;
|
||||
trantor::InetAddress localAddr_;
|
||||
trantor::InetAddress peerAddr_;
|
||||
bool isServer_{true};
|
||||
WebSocketMessageParser parser_;
|
||||
trantor::TimerId pingTimerId_{trantor::InvalidTimerId};
|
||||
std::vector<uint32_t> masks_;
|
||||
std::atomic<bool> usingMask_;
|
||||
|
||||
std::function<void(std::string &&,
|
||||
const WebSocketConnectionImplPtr &,
|
||||
const WebSocketMessageType &)>
|
||||
messageCallback_ = [](std::string &&,
|
||||
const WebSocketConnectionImplPtr &,
|
||||
const WebSocketMessageType &) {};
|
||||
std::function<void(const WebSocketConnectionImplPtr &)> closeCallback_ =
|
||||
[](const WebSocketConnectionImplPtr &) {};
|
||||
void sendWsData(const char *msg, uint64_t len, unsigned char opcode);
|
||||
void disablePingInLoop();
|
||||
void setPingMessageInLoop(std::string &&message,
|
||||
const std::chrono::duration<double> &interval);
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
Reference in New Issue
Block a user