This commit is contained in:
parent
ca63fd413b
commit
0511259075
@ -9,7 +9,6 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
class HttpSession;
|
class HttpSession;
|
||||||
class ChatRoom;
|
|
||||||
class SystemUsage;
|
class SystemUsage;
|
||||||
class IoContext;
|
class IoContext;
|
||||||
|
|
||||||
@ -53,7 +52,6 @@ private:
|
|||||||
std::shared_ptr<IoContext> m_ioContext;
|
std::shared_ptr<IoContext> m_ioContext;
|
||||||
std::shared_ptr<boost::urls::router<RequestHandler>> m_router;
|
std::shared_ptr<boost::urls::router<RequestHandler>> m_router;
|
||||||
std::shared_ptr<boost::asio::system_timer> m_timer;
|
std::shared_ptr<boost::asio::system_timer> m_timer;
|
||||||
std::shared_ptr<ChatRoom> m_charRoom;
|
|
||||||
std::shared_ptr<SystemUsage> m_systemUsage;
|
std::shared_ptr<SystemUsage> m_systemUsage;
|
||||||
std::shared_ptr<Nng::Asio::Socket> m_replyer;
|
std::shared_ptr<Nng::Asio::Socket> m_replyer;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
find_package(Boost COMPONENTS program_options json process REQUIRED)
|
find_package(Boost COMPONENTS program_options json process REQUIRED)
|
||||||
|
|
||||||
add_subdirectory(ChatRoom)
|
|
||||||
add_subdirectory(WebRTC)
|
add_subdirectory(WebRTC)
|
||||||
|
|
||||||
add_executable(Server main.cpp
|
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;
|
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;
|
#error_page 404 /404.html;
|
||||||
|
|
||||||
# redirect server error pages to the static page /50x.html
|
# redirect server error pages to the static page /50x.html
|
||||||
|
Loading…
Reference in New Issue
Block a user