#ifndef PEERCONNECTION_SAMPLES_CLIENT_CONDUCTOR_H_
#define PEERCONNECTION_SAMPLES_CLIENT_CONDUCTOR_H_
#pragma once
#include <map>
#include <set>
#include <string>
#include <memory>
#include <Poco/URI.h>
//#include "boost_ipc/IPCServer.h"
//#include "boost_ipc/StreamIPCServer.h"
#include "webrtc/base/thread.h"
#include "webrtc/PeerConnectionSession.h"
#include "webrtc/WebRtcVP8Encoder.h"
#include "channel/SocketIOChannel.h"
namespace CC {
class Conductor:
public rtc::RefCountInterface,
public rtc::MessageHandler,
public SocketIOChannelObserver,
public PeerConnectionSessionObserver,
public fl2::WebRtcVP8EncoderCallback,
public rtc::Runnable
{
public:
enum {
MSG_ON_SIGNALING_JSON,
MSG_ON_SIGNALING_DISCONNECT,
MSG_ON_RAW_VIDEO_FRAME,
MSG_ON_SHARED_ENCODED_VIDEO_FRAME,
MSG_ON_PCM_AUDIO_FRAME,
MSG_ON_REMOVE_USER,
MSG_ON_MAINWINDOW_MESSAGE,
MSG_ON_PC_MESSAGE_CHECK,
MSG_ON_PC_MESSAGE,
MSG_ON_PC_CONNECT,
MSG_ON_PC_DISCONNECT,
MSG_ON_PC_SESSION_EMPTIED,
MSG_ON_CLOSE
};
Conductor(std::string id);
virtual ~Conductor();
void StartLogin(const Poco::URI& uri);
// *** rtc::MessageHandler ***
virtual void OnMessage(rtc::Message* msg);
// *** SocketIOChannelObserver ***
virtual void onSignalingJSON(Object::Ptr& arg);
virtual void onSignalingMessage(std::string& arg);
virtual void onSignalingEvent(int eventid, void* arg);
// *** PeerConnectionSessionObserver ***
virtual void onEncodedVideoFrame(const std::string& clientid, shared_ptr<WrapEncodedFrame>& cf, const std::string& source);
virtual void onRequestKeyEncodedVideoFrame(PeerConnectionSessionInterface::FrameMode mode);
virtual void onSetEncodingRates(const std::string& clientid, PeerConnectionSessionInterface::FrameMode mode, uint32_t newBitRate, uint32_t frameRate);
virtual void onRawVideoFrame(const std::string& clientid, const webrtc::VideoFrame* frame, const std::string& source);
virtual void onPCMAudioFrame(const std::string& clientid, shared_ptr<CaptureFrame>& cf, const std::string& source);
virtual void onPeerConnectionConnect(const std::string& clientid, const std::string& source);
virtual void onPeerConnectionDisconnect(const std::string& clientid, const std::string& source);
virtual void onPeerConnectionSessionEmptied(const std::string& clientid);
virtual void sendPeerConnectionMessage(const std::string& destid, const Object::Ptr& msg);
// *** WebRtcVP8EncoderCallback ***
virtual void onVP8EncodedFrame(shared_ptr<WrapEncodedFrame>& frame, int id);
void DeletePeerConnection();
void quit() { // Post the close msg in another thread to prevent deadlock
quitThread.reset(new rtc::Thread);
quitThread->Start(this);
}
virtual void Run(rtc::Thread* t/*unused*/) {
thread->Post(RTC_FROM_HERE, this, MSG_ON_CLOSE);
}
protected:
rtc::Thread *thread;
std::shared_ptr<CC::SocketIOChannel> channel_client;
std::map<std::string, std::unique_ptr<PeerConnectionSessionInterface> > sessions;
std::unique_ptr<fl2::WebRtcVP8Encoder> vp8Encoders[PeerConnectionSessionInterface::NO_VIDEO_FRAME];
std::unique_ptr<webrtc::VideoFrame> lastFrame;
time64_t lastFrameRtcTime;
time64_t startRtcTime;
time64_t lastAdjustHighestModeTime;
std::string mainClient;
bool mainClientReady;
std::string myid;
bool _runTest;
Poco::URI _uri;
std::string channelId;
std::unique_ptr<rtc::Thread> quitThread;
};
}
#endif // PEERCONNECTION_SAMPLES_CLIENT_CONDUCTOR_H_
main.cc
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <Poco/URI.h>
#include <Poco/Logger.h>
#include <Poco/AutoPtr.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/FileChannel.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include "conductor.h"
#include "channel/SocketIOChannel.h"
#include "webrtc/PeerConnectionSessionInterface.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/ssladapter.h"
#include "utils/flags/commonFlagdefs.h"
#include "utils/flags/flagdefs.h"
using Poco::AutoPtr;
using Poco::Logger;
using rtc::FlagList;
rtc::Thread* thread;
rtc::scoped_refptr<CC::Conductor> conductor = NULL;
void my_handler(int s){
printf("Caught signal %d\n",s);
conductor->quit();
}
std::string getRandomString(int length) {
srand(time(0));
std::stringstream s;
char alphanum[] = "0123456789"
// "!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum) - 1;
for (int i = 0; i < length; i++)
s << alphanum[rand() % stringLength];
return s.str();
}
int main(int argc, char* argv[]) {
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
sigaction(SIGTERM, &sigIntHandler, NULL);
FlagList::SetFlagsFromCommandLine(&argc, argv, true);
if (FLAG_help) {
FlagList::Print(NULL, false);
return 0;
}
std::string id = FLAG_ID;
if(id=="(random generated)") {
id = getRandomString(10);
}
if(FLAG_sioLog) {
AutoPtr<Poco::Formatter> formatter(new Poco::PatternFormatter("%y%m%d-%H%M%S.%i %t"));
formatter->setProperty("times","local");
AutoPtr<Poco::Channel> debugChannel;
if(FLAG_debugLogPath[0]=='\0') {
debugChannel.assign(new Poco::ConsoleChannel());
} else {
debugChannel.assign(new Poco::FileChannel(std::string(FLAG_debugLogPath)+"/su_sio_"+id+".log"));
debugChannel->setProperty("rotation", "2 M");// Write a new file every 2 MBytes
debugChannel->setProperty("archive", "number");// Append a number for archived files
debugChannel->setProperty("compress", "true");// Compress the archived files
}
AutoPtr<Poco::Channel> formattingChannel(new Poco::FormattingChannel(formatter, debugChannel));
Logger::create("SIOClientLog", formattingChannel);
}
Poco::URI temp_uri(FLAG_SERVER);
rtc::InitializeSSL();
rtc::AutoThread auto_thread;
thread = rtc::Thread::Current();
// --- Create debug logger ---
{
AutoPtr<Poco::Formatter> formatter(new Poco::PatternFormatter("%y%m%d-%H%M%S.%i %t"));
formatter->setProperty("times","local");
AutoPtr<Poco::Channel> debugChannel;
if(FLAG_debugLogPath[0]=='\0') {
debugChannel.assign(new Poco::ConsoleChannel());
} else {
debugChannel.assign(new Poco::FileChannel(std::string(FLAG_debugLogPath)+"/su_"+id+".log"));
debugChannel->setProperty("rotation", "2 M");// Write a new file every 10 MBytes
debugChannel->setProperty("archive", "number");// Append a number for archived files
debugChannel->setProperty("compress", "true");// Compress the archived files
}
AutoPtr<Poco::Channel> formattingChannel(new Poco::FormattingChannel(formatter, debugChannel));
Logger::create("DebugLog", formattingChannel);
}
Logger& logger = Logger::get("DebugLog");
logger.information("Debug logger start");
// ------
if(FLAG_statusReportServer[0]!='\0') {
Poco::URI report_uri(FLAG_statusReportServer);
logger.information("status reported to %s", std::string(FLAG_statusReportServer));
HTTPClientSession session(report_uri.getHost(), report_uri.getPort());
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, report_uri.getPathEtc(),
Poco::Net::HTTPMessage::HTTP_1_1);
req.setContentLength(0);
Poco::Net::HTTPResponse res;
session.sendRequest(req);
session.receiveResponse(res);
logger.information("res: %d, %s", (int)res.getStatus(), res.getReason());
}
conductor = new rtc::RefCountedObject<CC::Conductor>(id);
conductor->StartLogin(temp_uri);
thread->Run();
conductor = NULL;
thread->set_socketserver(NULL);
rtc::CleanupSSL();
logger.information("program exit");
return 0;
}