리버스 엔지니어링으로 진행
클라이언트를 먼저 시작한다.
서버에 접속하기
bool MainWnd::OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT* result) {
// ...
case WM_COMMAND:
if (button_ == reinterpret_cast<HWND>(lp)) {
if (BN_CLICKED == HIWORD(wp))
OnDefaultAction();
} else if (listbox_ == reinterpret_cast<HWND>(lp)) {
if (LBN_DBLCLK == HIWORD(wp)) {
OnDefaultAction();
}
}
void MainWnd::OnDefaultAction() {
if (!callback_)
return;
if (ui_ == CONNECT_TO_SERVER) {
std::string server(GetWindowText(edit1_));
std::string port_str(GetWindowText(edit2_));
int port = port_str.length() ? atoi(port_str.c_str()) : 0;
callback_->StartLogin(server, port);
}
// ...
참고로 callback_의 지정은
void MainWnd::RegisterObserver(MainWndCallback* callback) {
callback_ = callback;
}
// Conductor 생성자에서 지정
Conductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd)
: peer_id_(-1), loopback_(false), client_(client), main_wnd_(main_wnd) {
printf("Conductor::Conductor\n");
client_->RegisterObserver(this);
main_wnd->RegisterObserver(this);
}
// main에서 conductor 생성
int PASCAL wWinMain(HINSTANCE instance,
HINSTANCE prev_instance,
wchar_t* cmd_line,
int cmd_show) {
// ...
MainWnd wnd(FLAG_server, FLAG_port, FLAG_autoconnect, FLAG_autocall);
if (!wnd.Create()) {
RTC_NOTREACHED();
return -1;
}
rtc::InitializeSSL();
PeerConnectionClient client;
rtc::scoped_refptr<Conductor> conductor(
new rtc::RefCountedObject<Conductor>(&client, &wnd));
다시 void MainWnd::OnDefaultAction()
로 돌아가서
void MainWnd::OnDefaultAction() {
if (!callback_)
return;
if (ui_ == CONNECT_TO_SERVER) {
std::string server(GetWindowText(edit1_));
std::string port_str(GetWindowText(edit2_));
int port = port_str.length() ? atoi(port_str.c_str()) : 0;
callback_->StartLogin(server, port);
}
// ...
void Conductor::StartLogin(const std::string& server, int port) {
printf("Conductor::StartLogin\n");
if (client_->is_connected())
return;
server_ = server;
client_->Connect(server, port, GetPeerName());
// (참고) PeerConnectionClient* client_;
}
참고 PeerConnectionClient* client_
의 생성은
// 역시 main에서 client 생성
int PASCAL wWinMain(HINSTANCE instance,
HINSTANCE prev_instance,
wchar_t* cmd_line,
int cmd_show) {
// ...
rtc::InitializeSSL();
PeerConnectionClient client;
rtc::scoped_refptr<Conductor> conductor(
new rtc::RefCountedObject<Conductor>(&client, &wnd));
다시 Conductor::StartLogin
void Conductor::StartLogin(const std::string& server, int port) {
printf("Conductor::StartLogin\n");
if (client_->is_connected())
return;
server_ = server;
client_->Connect(server, port, GetPeerName());
}
void PeerConnectionClient::Connect(const std::string& server,
int port,
const std::string& client_name) {
RTC_DCHECK(!server.empty());
RTC_DCHECK(!client_name.empty());
if (state_ != NOT_CONNECTED) {
RTC_LOG(WARNING)
<< "The client must not be connected before you can call Connect()";
callback_->OnServerConnectionFailure();
return;
}
if (server.empty() || client_name.empty()) {
callback_->OnServerConnectionFailure();
return;
}
if (port <= 0)
port = kDefaultServerPort;
// rtc::SocketAddress server_address_;
server_address_.SetIP(server);
server_address_.SetPort(port);
client_name_ = client_name;
if (server_address_.IsUnresolvedIP()) {
// 여긴 이렇게 쓴다고 그냥 받아들이자.
state_ = RESOLVING;
resolver_ = new rtc::AsyncResolver();
resolver_->SignalDone.connect(this, &PeerConnectionClient::OnResolveResult);
resolver_->Start(server_address_);
} else {
DoConnect();
}
}