Skip to content

Commit f771631

Browse files
Hub Connection Builder (aspnet#20)
1 parent 0a35552 commit f771631

22 files changed

+356
-197
lines changed

include/signalrclient/http_client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace signalr
5151
class http_client
5252
{
5353
public:
54-
virtual void send(std::string url, const http_request& request, std::function<void(const http_response&, std::exception_ptr)> callback) = 0;
54+
virtual void send(const std::string& url, const http_request& request, std::function<void(const http_response&, std::exception_ptr)> callback) = 0;
5555

5656
virtual ~http_client() {}
5757
};

include/signalrclient/hub_connection.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,26 @@
1414

1515
namespace signalr
1616
{
17+
class http_client;
18+
class websocket_client;
1719
class hub_connection_impl;
20+
class hub_connection_builder;
1821

1922
class hub_connection
2023
{
2124
public:
2225
typedef std::function<void __cdecl (const signalr::value&)> method_invoked_handler;
2326

24-
SIGNALRCLIENT_API explicit hub_connection(const std::string& url, trace_level trace_level = trace_level::all,
25-
std::shared_ptr<log_writer> log_writer = nullptr);
26-
2727
SIGNALRCLIENT_API ~hub_connection();
2828

2929
hub_connection(const hub_connection&) = delete;
3030

3131
hub_connection& operator=(const hub_connection&) = delete;
3232

33+
SIGNALRCLIENT_API hub_connection(hub_connection&&) noexcept;
34+
35+
SIGNALRCLIENT_API hub_connection& operator=(hub_connection&&) noexcept;
36+
3337
SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept;
3438
SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept;
3539

@@ -47,6 +51,12 @@ namespace signalr
4751
SIGNALRCLIENT_API void send(const std::string& method_name, const signalr::value& arguments = signalr::value(), std::function<void(std::exception_ptr)> callback = [](std::exception_ptr) {}) noexcept;
4852

4953
private:
54+
friend class hub_connection_builder;
55+
56+
explicit hub_connection(const std::string& url, trace_level trace_level = trace_level::all,
57+
std::shared_ptr<log_writer> log_writer = nullptr, std::shared_ptr<http_client> http_client = nullptr,
58+
std::function<std::shared_ptr<websocket_client>()> websocket_factory = nullptr);
59+
5060
std::shared_ptr<hub_connection_impl> m_pImpl;
5161
};
5262
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
#pragma once
5+
6+
#include "_exports.h"
7+
#include "hub_connection.h"
8+
#include <memory>
9+
#include "websocket_client.h"
10+
#include "http_client.h"
11+
12+
namespace signalr
13+
{
14+
class hub_connection_builder
15+
{
16+
public:
17+
SIGNALRCLIENT_API static hub_connection_builder create(const std::string& url);
18+
19+
SIGNALRCLIENT_API ~hub_connection_builder();
20+
21+
SIGNALRCLIENT_API hub_connection_builder(const hub_connection_builder&);
22+
23+
SIGNALRCLIENT_API hub_connection_builder(hub_connection_builder&&) noexcept;
24+
25+
SIGNALRCLIENT_API hub_connection_builder& operator=(hub_connection_builder&&) noexcept;
26+
27+
SIGNALRCLIENT_API hub_connection_builder& operator=(const hub_connection_builder&);
28+
29+
SIGNALRCLIENT_API hub_connection_builder& with_logging(std::shared_ptr<log_writer> logger, trace_level logLevel);
30+
31+
SIGNALRCLIENT_API hub_connection_builder& with_websocket_factory(std::function<std::shared_ptr<websocket_client>()> factory);
32+
33+
SIGNALRCLIENT_API hub_connection_builder& with_http_client(std::shared_ptr<http_client> http_client);
34+
35+
SIGNALRCLIENT_API hub_connection build();
36+
private:
37+
hub_connection_builder(const std::string& url);
38+
39+
std::string m_url;
40+
std::shared_ptr<log_writer> m_logger;
41+
trace_level m_log_level;
42+
std::function<std::shared_ptr<websocket_client>()> m_websocket_factory;
43+
std::shared_ptr<http_client> m_http_client;
44+
};
45+
}

samples/HubConnectionSample/HubConnectionSample.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <iostream>
55
#include <sstream>
6-
#include "hub_connection.h"
6+
#include "hub_connection_builder.h"
77
#include "log_writer.h"
88
#include <future>
99
#include "signalr_value.h"
@@ -50,7 +50,10 @@ void send_message(signalr::hub_connection& connection, const std::string& messag
5050

5151
void chat()
5252
{
53-
signalr::hub_connection connection("http://localhost:5000/default", signalr::trace_level::all, std::make_shared<logger>());
53+
signalr::hub_connection connection = signalr::hub_connection_builder::create("http://localhost:5000/default")
54+
.with_logging(std::make_shared <logger>(), signalr::trace_level::all)
55+
.build();
56+
5457
connection.on("Send", [](const signalr::value & m)
5558
{
5659
std::cout << std::endl << m.as_array()[0].as_string() << std::endl << "Enter your message: ";

src/signalrclient/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set (SOURCES
66
default_websocket_client.cpp
77
handshake_protocol.cpp
88
hub_connection.cpp
9+
hub_connection_builder.cpp
910
hub_connection_impl.cpp
1011
json_helpers.cpp
1112
json_hub_protocol.cpp

src/signalrclient/connection_impl.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "make_unique.h"
1616
#include "completion_event.h"
1717
#include <assert.h>
18+
#include "signalrclient/websocket_client.h"
19+
#include "default_websocket_client.h"
1820

1921
namespace signalr
2022
{
@@ -27,14 +29,14 @@ namespace signalr
2729

2830
std::shared_ptr<connection_impl> connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer)
2931
{
30-
return connection_impl::create(url, trace_level, log_writer, nullptr, std::make_unique<transport_factory>());
32+
return connection_impl::create(url, trace_level, log_writer, nullptr, nullptr);
3133
}
3234

3335
std::shared_ptr<connection_impl> connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
34-
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory)
36+
std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>()> websocket_factory)
3537
{
3638
return std::shared_ptr<connection_impl>(new connection_impl(url, trace_level,
37-
log_writer ? log_writer : std::make_shared<trace_log_writer>(), std::move(http_client), std::move(transport_factory)));
39+
log_writer ? log_writer : std::make_shared<trace_log_writer>(), http_client, websocket_factory));
3840
}
3941

4042
connection_impl::connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
@@ -52,6 +54,32 @@ namespace signalr
5254
}
5355
}
5456

57+
connection_impl::connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
58+
std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>()> websocket_factory)
59+
: m_base_http://github.com/url(url), m_connection_state(connection_state::disconnected), m_logger(log_writer, trace_level), m_transport(nullptr),
60+
m_message_received([](const std::string&) noexcept {}), m_disconnected([]() noexcept {})
61+
{
62+
if (http_client != nullptr)
63+
{
64+
m_http_client = std::move(http_client);
65+
}
66+
else
67+
{
68+
#ifdef USE_CPPRESTSDK
69+
m_http_client = std::unique_ptr<class http_client>(new default_http_client());
70+
#endif
71+
}
72+
73+
if (websocket_factory == nullptr)
74+
{
75+
#ifdef USE_CPPRESTSDK
76+
websocket_factory = []() { return std::make_shared<default_websocket_client>(); };
77+
#endif
78+
}
79+
80+
m_transport_factory = std::unique_ptr<transport_factory>(new transport_factory(m_http_client, websocket_factory));
81+
}
82+
5583
connection_impl::~connection_impl()
5684
{
5785
try

src/signalrclient/connection_impl.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
namespace signalr
1818
{
19+
class websocket_client;
20+
1921
// Note:
2022
// Factory methods and private constructors prevent from using this class incorrectly. Because this class
2123
// derives from `std::enable_shared_from_this` the instance has to be owned by a `std::shared_ptr` whenever
@@ -27,7 +29,7 @@ namespace signalr
2729
static std::shared_ptr<connection_impl> create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer);
2830

2931
static std::shared_ptr<connection_impl> create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
30-
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory);
32+
std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>()> websocket_factory);
3133

3234
connection_impl(const connection_impl&) = delete;
3335

@@ -62,11 +64,14 @@ namespace signalr
6264
cancellation_token m_start_completed_event;
6365
std::string m_connection_id;
6466
std::string m_connection_token;
65-
std::unique_ptr<http_client> m_http_client;
67+
std::shared_ptr<http_client> m_http_client;
6668

6769
connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
6870
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory);
6971

72+
connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
73+
std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>()> websocket_factory);
74+
7075
void start_transport(const std::string& url, std::function<void(std::shared_ptr<transport>, std::exception_ptr)> callback);
7176
void send_connect_request(const std::shared_ptr<transport>& transport,
7277
const std::string& url, std::function<void(std::exception_ptr)> callback);

src/signalrclient/default_http_client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace signalr
1212
{
13-
void default_http_client::send(std::string url, const http_request& request, std::function<void(const http_response&, std::exception_ptr)> callback)
13+
void default_http_client::send(const std::string& url, const http_request& request, std::function<void(const http_response&, std::exception_ptr)> callback)
1414
{
1515
web::http::method method;
1616
if (request.method == http_method::GET)

src/signalrclient/default_http_client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ namespace signalr
1010
class default_http_client : public http_client
1111
{
1212
public:
13-
void send(std::string url, const http_request& request, std::function<void(const http_response&, std::exception_ptr)> callback) override;
13+
void send(const std::string& url, const http_request& request, std::function<void(const http_response&, std::exception_ptr)> callback) override;
1414
};
1515
}

src/signalrclient/hub_connection.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,30 @@
55
#include "signalrclient/hub_connection.h"
66
#include "hub_connection_impl.h"
77
#include "signalrclient/signalr_exception.h"
8+
#include "signalrclient/http_client.h"
9+
#include "signalrclient/websocket_client.h"
810

911
namespace signalr
1012
{
1113
hub_connection::hub_connection(const std::string& url,
12-
trace_level trace_level, std::shared_ptr<log_writer> log_writer)
13-
: m_pImpl(hub_connection_impl::create(url, trace_level, std::move(log_writer)))
14+
trace_level trace_level, std::shared_ptr<log_writer> log_writer, std::shared_ptr<http_client> http_client,
15+
std::function<std::shared_ptr<websocket_client>()> websocket_factory)
16+
: m_pImpl(hub_connection_impl::create(url, trace_level, log_writer, http_client, websocket_factory))
1417
{}
1518

19+
hub_connection::hub_connection(hub_connection&& rhs) noexcept
20+
: m_pImpl(std::move(rhs.m_pImpl))
21+
{}
22+
23+
hub_connection& hub_connection::operator=(hub_connection&& rhs) noexcept
24+
{
25+
m_pImpl = std::move(rhs.m_pImpl);
26+
27+
return *this;
28+
}
29+
1630
// Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to
17-
// undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/
31+
// undefined behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/
1832
hub_connection::~hub_connection() = default;
1933

2034
void hub_connection::start(std::function<void(std::exception_ptr)> callback) noexcept

0 commit comments

Comments
 (0)