This commit is contained in:
parent
ca63fd413b
commit
0511259075
@ -9,7 +9,6 @@
|
||||
#include <thread>
|
||||
|
||||
class HttpSession;
|
||||
class ChatRoom;
|
||||
class SystemUsage;
|
||||
class IoContext;
|
||||
|
||||
@ -53,7 +52,6 @@ private:
|
||||
std::shared_ptr<IoContext> m_ioContext;
|
||||
std::shared_ptr<boost::urls::router<RequestHandler>> m_router;
|
||||
std::shared_ptr<boost::asio::system_timer> m_timer;
|
||||
std::shared_ptr<ChatRoom> m_charRoom;
|
||||
std::shared_ptr<SystemUsage> m_systemUsage;
|
||||
std::shared_ptr<Nng::Asio::Socket> m_replyer;
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
find_package(Boost COMPONENTS program_options json process REQUIRED)
|
||||
|
||||
add_subdirectory(ChatRoom)
|
||||
add_subdirectory(WebRTC)
|
||||
|
||||
add_executable(Server main.cpp
|
||||
|
@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
add_library(ChatRoom
|
||||
ChatRoom.h ChatRoom.cpp
|
||||
WebSocketChatSession.h WebSocketChatSession.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(ChatRoom
|
||||
PUBLIC Universal
|
||||
)
|
@ -1,31 +0,0 @@
|
||||
#include "ChatRoom.h"
|
||||
#include "WebSocketChatSession.h"
|
||||
|
||||
void ChatRoom::join(WebSocketSession *session) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_sessions.insert(session);
|
||||
}
|
||||
|
||||
void ChatRoom::leave(WebSocketSession *session) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_sessions.erase(session);
|
||||
}
|
||||
|
||||
void ChatRoom::send(std::string message) {
|
||||
auto const ss = std::make_shared<std::string const>(std::move(message));
|
||||
|
||||
// Make a local list of all the weak pointers representing
|
||||
// the sessions, so we can do the actual sending without
|
||||
// holding the mutex:
|
||||
std::vector<std::weak_ptr<WebSocketSession>> v;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
v.reserve(m_sessions.size());
|
||||
for (auto p : m_sessions) v.emplace_back(p->weak_from_this());
|
||||
}
|
||||
|
||||
// For each session in our local list, try to acquire a strong
|
||||
// pointer. If successful, then send the message on that session.
|
||||
for (auto const &wp : v)
|
||||
if (auto sp = wp.lock()) sp->send(ss);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#ifndef __CHATROOM_H__
|
||||
#define __CHATROOM_H__
|
||||
|
||||
#include "Singleton.h"
|
||||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
|
||||
class WebSocketSession;
|
||||
|
||||
class ChatRoom {
|
||||
public:
|
||||
void join(WebSocketSession *session);
|
||||
void leave(WebSocketSession *session);
|
||||
/**
|
||||
* @brief Broadcast a message to all websocket client sessions
|
||||
*/
|
||||
void send(std::string message);
|
||||
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
std::unordered_set<WebSocketSession *> m_sessions;
|
||||
};
|
||||
#endif // __CHATROOM_H__
|
@ -1,88 +0,0 @@
|
||||
#include "WebSocketChatSession.h"
|
||||
#include "ChatRoom.h"
|
||||
#include "StringUtility.h"
|
||||
#include <boost/json/parse.hpp>
|
||||
#include <boost/json/serialize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
WebSocketSession::WebSocketSession(boost::asio::ip::tcp::socket &&socket) : m_ws(std::move(socket)) {
|
||||
}
|
||||
|
||||
WebSocketSession::~WebSocketSession() {
|
||||
auto chatRoom = Amass::Singleton<ChatRoom>::instance();
|
||||
chatRoom->leave(this);
|
||||
}
|
||||
|
||||
void WebSocketSession::onAccept(boost::beast::error_code ec) {
|
||||
if (ec) {
|
||||
if (ec == boost::asio::error::operation_aborted || ec == boost::beast::websocket::error::closed) return;
|
||||
std::cerr << "accept: " << ec.message() << "\n";
|
||||
return;
|
||||
}
|
||||
LOG(info) << "accept websocket target: " << m_target;
|
||||
if (m_target.find("/webrtc") == 0) {
|
||||
auto splits = Amass::StringUtility::split(m_target, "/");
|
||||
if (!splits.empty()) m_id = splits.back();
|
||||
}
|
||||
|
||||
auto chatRoom = Amass::Singleton<ChatRoom>::instance();
|
||||
chatRoom->join(this);
|
||||
|
||||
// Read a message
|
||||
m_ws.async_read(m_buffer, boost::beast::bind_front_handler(&WebSocketSession::on_read, shared_from_this()));
|
||||
}
|
||||
|
||||
void WebSocketSession::on_read(boost::beast::error_code ec, std::size_t) {
|
||||
if (ec) {
|
||||
// Don't report these
|
||||
if (ec == boost::asio::error::operation_aborted || ec == boost::beast::websocket::error::closed) return;
|
||||
LOG(error) << "read: " << ec.message();
|
||||
return;
|
||||
}
|
||||
auto message = boost::beast::buffers_to_string(m_buffer.data());
|
||||
LOG(info) << message;
|
||||
auto chatRoom = Amass::Singleton<ChatRoom>::instance();
|
||||
chatRoom->send(message); // Send to all connections
|
||||
|
||||
m_buffer.consume(m_buffer.size()); // Clear the buffer
|
||||
m_ws.async_read(m_buffer, boost::beast::bind_front_handler(&WebSocketSession::on_read, shared_from_this()));
|
||||
}
|
||||
|
||||
void WebSocketSession::send(std::shared_ptr<std::string const> const &ss) {
|
||||
// Post our work to the strand, this ensures
|
||||
// that the members of `this` will not be
|
||||
// accessed concurrently.
|
||||
m_ws.text();
|
||||
boost::asio::post(m_ws.get_executor(),
|
||||
boost::beast::bind_front_handler(&WebSocketSession::onSend, shared_from_this(), ss));
|
||||
}
|
||||
|
||||
void WebSocketSession::onSend(std::shared_ptr<std::string const> const &ss) {
|
||||
// Always add to queue
|
||||
m_queue.push_back(ss);
|
||||
|
||||
// Are we already writing?
|
||||
if (m_queue.size() > 1) return;
|
||||
|
||||
// We are not currently writing, so send this immediately
|
||||
m_ws.async_write(boost::asio::buffer(*m_queue.front()),
|
||||
boost::beast::bind_front_handler(&WebSocketSession::on_write, shared_from_this()));
|
||||
}
|
||||
|
||||
void WebSocketSession::on_write(boost::beast::error_code ec, std::size_t) {
|
||||
// Handle the error, if any
|
||||
if (ec) {
|
||||
// Don't report these
|
||||
if (ec == boost::asio::error::operation_aborted || ec == boost::beast::websocket::error::closed) return;
|
||||
std::cerr << "write: " << ec.message() << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the string from the queue
|
||||
m_queue.erase(m_queue.begin());
|
||||
|
||||
// Send the next message if any
|
||||
if (!m_queue.empty())
|
||||
m_ws.async_write(boost::asio::buffer(*m_queue.front()),
|
||||
boost::beast::bind_front_handler(&WebSocketSession::on_write, shared_from_this()));
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
#ifndef WEBSOCKETSESSION_H
|
||||
#define WEBSOCKETSESSION_H
|
||||
|
||||
#include "BoostLog.h"
|
||||
#include <boost/beast.hpp>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents an active WebSocket connection to the server
|
||||
*/
|
||||
class WebSocketSession : public std::enable_shared_from_this<WebSocketSession> {
|
||||
public:
|
||||
WebSocketSession(boost::asio::ip::tcp::socket &&socket);
|
||||
|
||||
~WebSocketSession();
|
||||
|
||||
template <class Body, class Allocator>
|
||||
void run(boost::beast::http::request<Body, boost::beast::http::basic_fields<Allocator>> request) {
|
||||
using namespace boost::beast::http;
|
||||
using namespace boost::beast::websocket;
|
||||
// Set suggested timeout settings for the websocket
|
||||
m_ws.set_option(stream_base::timeout::suggested(boost::beast::role_type::server));
|
||||
m_target = request.target();
|
||||
// Set a decorator to change the Server of the handshake
|
||||
m_ws.set_option(stream_base::decorator([](response_type &response) {
|
||||
response.set(field::server, std::string(BOOST_BEAST_VERSION_STRING) + " websocket-chat-multi");
|
||||
}));
|
||||
// LOG(info) << request.base().target(); //get path
|
||||
// Accept the websocket handshake
|
||||
m_ws.async_accept(request, [self{shared_from_this()}](boost::beast::error_code ec) { self->onAccept(ec); });
|
||||
}
|
||||
|
||||
// Send a message
|
||||
void send(std::shared_ptr<std::string const> const &ss);
|
||||
|
||||
protected:
|
||||
void onAccept(boost::beast::error_code ec);
|
||||
void on_read(boost::beast::error_code ec, std::size_t bytes_transferred);
|
||||
void on_write(boost::beast::error_code ec, std::size_t bytes_transferred);
|
||||
void onSend(std::shared_ptr<std::string const> const &ss);
|
||||
|
||||
private:
|
||||
std::string m_target;
|
||||
boost::beast::flat_buffer m_buffer;
|
||||
boost::beast::websocket::stream<boost::beast::tcp_stream> m_ws;
|
||||
std::vector<std::shared_ptr<std::string const>> m_queue;
|
||||
std::string m_id;
|
||||
};
|
||||
|
||||
#endif // WEBSOCKETSESSION_H
|
@ -91,17 +91,6 @@ location ~ /notify.*$ {
|
||||
proxy_pass http://local;
|
||||
}
|
||||
|
||||
location /Younger/ChatRoom {
|
||||
|
||||
proxy_pass http://local;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_read_timeout 1200s;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
# redirect server error pages to the static page /50x.html
|
||||
|
Loading…
Reference in New Issue
Block a user