NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
websocket.hpp
浏览该文件的文档.
1#ifndef NEFORCE_NETWORK_HTTP_WEBSOCKET_HPP__
2#define NEFORCE_NETWORK_HTTP_WEBSOCKET_HPP__
3
10
20NEFORCE_BEGIN_NAMESPACE__
21NEFORCE_BEGIN_HTTP__
22
27
45
70
79 TEXT = 0x1,
80 BINARY = 0x2,
81 CLOSE = 0x8,
82 PING = 0x9,
83 PONG = 0xA
84};
85
86#pragma pack(push, 1)
102#pragma pack(pop)
103
105
106
131class NEFORCE_API websocket_server {
132public:
135
136private:
138 vector<session_ptr> sessions_;
139 mutable mutex sessions_mutex_;
140
141public:
142 websocket_server() = default;
143 ~websocket_server() = default;
144
145 websocket_server(const websocket_server&) = delete;
146 websocket_server& operator=(const websocket_server&) = delete;
147
148 websocket_server(websocket_server&&) noexcept = default;
149 websocket_server& operator=(websocket_server&&) noexcept = default;
150
156 void route(const string& path, session_handler handler) { route_handlers_[path] = _NEFORCE move(handler); }
157
165
170 void remove_session(const session_ptr& session);
171
178
183 size_t session_count() const noexcept {
184 lock<mutex> lk(sessions_mutex_);
185 return sessions_.size();
186 }
187};
188
211class NEFORCE_API websocket_session : public enable_shared_from_this<websocket_session> {
212public:
213 using message_handler = function<void(const string&, websocket_opcode)>;
214 using close_handler = function<void(websocket_status, const string&)>;
215 using error_handler = function<void(const exception&)>;
216
217private:
218 unique_ptr<tcp_socket> socket_;
219 websocket_server* server_;
220
221 atomic<bool> running_{false};
222 atomic_flag closed_once_;
223
224 thread read_thread_;
225 thread write_thread_;
226 thread heartbeat_thread_;
227
228 mutex write_mutex_;
229 condition_variable write_cv_;
230 queue<byte_vector> write_queue_;
231 queue<byte_vector> ctrl_queue_;
232
233 string fragment_buffer_;
234 websocket_opcode fragment_opcode_ = websocket_opcode::TEXT;
235 bool in_fragment_ = false;
236
237 atomic<bool> ping_pending_{false};
238 atomic<int64_t> last_pong_ms_{0};
239
240 message_handler on_message_;
241 close_handler on_close_;
242 error_handler on_error_;
243
244 bool queue_frame(byte_vector frame, bool is_control = false);
245 void write_loop() noexcept;
246
247 void read_loop() noexcept;
248 bool read_frame() noexcept;
249
250 bool dispatch(const websocket_frame_header& hdr, websocket_opcode opcode, string payload);
251 void deliver_message(const string& data, websocket_opcode opcode);
252
253 void send_close_frame(websocket_status status, const string& reason);
254 void handle_close_frame(string payload);
255
256 void heartbeat_loop() noexcept;
257
258 void do_stop(websocket_status status, const string& reason) noexcept;
259
260public:
266 explicit websocket_session(unique_ptr<tcp_socket> sock, websocket_server* server = nullptr);
267
272
273 websocket_session(const websocket_session&) = delete;
274 websocket_session& operator=(const websocket_session&) = delete;
275
281 void start();
282
288 void close(websocket_status status = websocket_status::NORMAL_CLOSURE, const string& reason = "");
289
293 void stop();
294
301 bool send(const string& data, websocket_opcode opcode = websocket_opcode::TEXT);
302
308 bool send_binary(const string& data) { return send(data, websocket_opcode::BINARY); }
309
314 bool is_open() const noexcept { return running_ && socket_->is_open(); }
315
320 void set_message_handler(message_handler handler) { on_message_ = _NEFORCE move(handler); }
321
326 void set_close_handler(close_handler handler) { on_close_ = _NEFORCE move(handler); }
327
332 void set_error_handler(error_handler handler) { on_error_ = _NEFORCE move(handler); }
333
338 tcp_socket& socket() noexcept { return *socket_; }
339
344 const tcp_socket& socket() const noexcept { return *socket_; }
345
350 ssl_socket* ssl_socket_ptr() noexcept { return dynamic_cast<ssl_socket*>(socket_.get()); }
351
356 const ssl_socket* ssl_socket_ptr() const noexcept { return dynamic_cast<const ssl_socket*>(socket_.get()); }
357};
358 // WebSocket
360 // HTTP
362
363NEFORCE_END_HTTP__
364NEFORCE_END_NAMESPACE__
365#endif // NEFORCE_NETWORK_HTTP_WEBSOCKET_HPP__
原子类型完整实现
函数包装器主模板声明
锁管理器模板
非递归互斥锁
文件路径类
队列容器适配器
共享智能指针类模板
SSL/TLS安全Socket类
TCP Socket类
线程类
独占智能指针
无序映射容器
动态大小数组容器
WebSocket服务器类
void route(const string &path, session_handler handler)
注册WebSocket路由
size_t session_count() const noexcept
获取活动会话数量
bool handle_upgrade(const http_request &request, unique_ptr< tcp_socket > sock)
处理WebSocket升级请求
void remove_session(const session_ptr &session)
移除会话
function< void(session_ptr)> session_handler
会话处理器类型
void broadcast(const string &data, websocket_opcode opcode=websocket_opcode::TEXT)
向所有会话广播消息
shared_ptr< websocket_session > session_ptr
会话智能指针类型
WebSocket会话类
ssl_socket * ssl_socket_ptr() noexcept
获取SSL socket指针
void start()
启动会话
function< void(websocket_status, const string &)> close_handler
关闭处理器类型
void set_error_handler(error_handler handler)
设置错误处理器
void close(websocket_status status=websocket_status::NORMAL_CLOSURE, const string &reason="")
关闭连接
function< void(const string &, websocket_opcode)> message_handler
消息处理器类型
bool is_open() const noexcept
检查连接是否开启
bool send(const string &data, websocket_opcode opcode=websocket_opcode::TEXT)
发送文本/二进制消息
bool send_binary(const string &data)
发送二进制消息
websocket_session(unique_ptr< tcp_socket > sock, websocket_server *server=nullptr)
构造函数
const tcp_socket & socket() const noexcept
获取底层socket常量引用
function< void(const exception &)> error_handler
错误处理器类型
void set_message_handler(message_handler handler)
设置消息处理器
tcp_socket & socket() noexcept
获取底层socket引用
void stop()
停止会话
const ssl_socket * ssl_socket_ptr() const noexcept
获取SSL socket常量指针
void set_close_handler(close_handler handler)
设置关闭处理器
条件变量行为
通用函数包装器
vector< byte_t > byte_vector
字节向量类型别名
unsigned char uint8_t
8位无符号整数类型
unsigned char byte_t
字节类型,定义为无符号字符
unsigned short uint16_t
16位无符号整数类型
http_server_request http_request
HTTP请求类型别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
websocket_opcode
WebSocket帧操作码
websocket_status
WebSocket关闭状态码
@ BINARY
二进制帧
@ POLICY_VIOLATION
策略违规
@ PROTOCOL_ERROR
协议错误
@ NO_STATUS_RCVD
未收到状态码
@ BAD_GATEWAY
错误的网关
@ TRY_AGAIN_LATER
稍后重试
@ INVALID_FRAME_PAYLOAD_DATA
无效帧负载
@ NORMAL_CLOSURE
正常关闭
@ SERVICE_RESTART
服务重启
@ UNSUPPORTED_DATA
不支持的数据类型
@ ABNORMAL_CLOSURE
异常关闭
@ GOING_AWAY
端点离开
@ MESSAGE_TOO_BIG
消息过大
@ TLS_HANDSHAKE
TLS握手失败
@ INTERNAL_ERROR
内部错误
@ MANDATORY_EXT
缺少必要扩展
HTTP服务器消息结构
队列容器适配器
共享智能指针实现
SSL/TLS安全Socket实现
通用原子类型模板
异常基类
WebSocket帧头部结构
byte_t fin
是否最后一帧
byte_t payload_len
负载长度
byte_t masked
是否掩码
线程管理类
无序映射容器