blob: 0c883ed470782e13858279ae2dacdbacbbac84d0 [file] [log] [blame]
// Copyright (c) 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_MOQT_TOOLS_CHAT_SERVER_H_
#define QUICHE_QUIC_MOQT_TOOLS_CHAT_SERVER_H_
#include <cstdint>
#include <fstream>
#include <list>
#include <memory>
#include <optional>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/proof_source.h"
#include "quiche/quic/moqt/moqt_known_track_publisher.h"
#include "quiche/quic/moqt/moqt_live_relay_queue.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_outgoing_queue.h"
#include "quiche/quic/moqt/moqt_priority.h"
#include "quiche/quic/moqt/moqt_publisher.h"
#include "quiche/quic/moqt/moqt_session.h"
#include "quiche/quic/moqt/moqt_track.h"
#include "quiche/quic/moqt/tools/moq_chat.h"
#include "quiche/quic/moqt/tools/moqt_server.h"
namespace moqt {
class ChatServer {
public:
ChatServer(std::unique_ptr<quic::ProofSource> proof_source,
absl::string_view chat_id, absl::string_view output_file);
~ChatServer();
class RemoteTrackVisitor : public SubscribeRemoteTrack::Visitor {
public:
explicit RemoteTrackVisitor(ChatServer* server);
void OnReply(const moqt::FullTrackName& full_track_name,
std::optional<FullSequence> largest_id,
std::optional<absl::string_view> reason_phrase) override;
void OnCanAckObjects(MoqtObjectAckFunction) override {}
void OnObjectFragment(
const moqt::FullTrackName& full_track_name, FullSequence sequence,
moqt::MoqtPriority /*publisher_priority*/,
moqt::MoqtObjectStatus /*status*/,
absl::string_view object, bool end_of_message) override;
private:
ChatServer* server_;
};
class ChatServerSessionHandler {
public:
ChatServerSessionHandler(MoqtSession* session, ChatServer* server);
~ChatServerSessionHandler();
void set_iterator(
const std::list<ChatServerSessionHandler>::const_iterator it) {
it_ = it;
}
private:
MoqtSession* session_; // Not owned.
// This design assumes that each server has exactly one username, although
// in theory there could be multiple users on one session.
std::optional<std::string> username_;
ChatServer* server_; // Not owned.
// The iterator of this entry in ChatServer::sessions_, so it can destroy
// itself later.
std::list<ChatServerSessionHandler>::const_iterator it_;
};
MoqtServer& moqt_server() { return server_; }
RemoteTrackVisitor* remote_track_visitor() { return &remote_track_visitor_; }
MoqtOutgoingQueue* catalog() { return catalog_.get(); }
void AddUser(absl::string_view username);
void DeleteUser(absl::string_view username);
void DeleteSession(std::list<ChatServerSessionHandler>::const_iterator it) {
sessions_.erase(it);
}
// Returns false if no output file is set.
bool WriteToFile(absl::string_view username, absl::string_view message);
MoqtPublisher* publisher() { return &publisher_; }
MoqChatStrings& strings() { return strings_; }
int num_users() const { return user_queues_.size(); }
private:
absl::StatusOr<MoqtConfigureSessionCallback> IncomingSessionHandler(
absl::string_view path);
MoqtIncomingSessionCallback incoming_session_callback_ =
[&](absl::string_view path) { return IncomingSessionHandler(path); };
bool is_running_ = true;
MoqtServer server_;
std::list<ChatServerSessionHandler> sessions_;
MoqChatStrings strings_;
MoqtKnownTrackPublisher publisher_;
std::shared_ptr<MoqtOutgoingQueue> catalog_;
RemoteTrackVisitor remote_track_visitor_;
// indexed by username
absl::flat_hash_map<std::string, std::shared_ptr<MoqtLiveRelayQueue>>
user_queues_;
std::string output_filename_;
std::ofstream output_file_;
};
} // namespace moqt
#endif // QUICHE_QUIC_MOQT_TOOLS_CHAT_SERVER_H_