Feel free to ask questions - Chat on Gitter
Contents:
Now it's possible to continuously stream multipart data to the client.
For example, you can implement multipart/x-mixed-replace
video stream.
Both Simple-APIs and Async-APIs available.
using namespace oatpp::web::mime::multipart;
class MPStream : public Multipart {
public:
MPStream()
: Multipart(generateRandomBoundary())
{}
std::shared_ptr<Part> readNextPart(async::Action& action /* For Simple-API action is ignored */) override {
std::this_thread::sleep_for(std::chrono::seconds(1)); // For Simple-API you may sleep just like that
oatpp::String frameData = "<frame-binary-jpeg-data>" // frame data. One jpeg image.
auto part = std::make_shared<Part>();
part->putHeader(Header::CONTENT_TYPE, "image/jpeg");
part->setDataInfo(std::make_shared<oatpp::data::stream::BufferInputStream>(frameData));
return part;
}
void writeNextPart(const std::shared_ptr<Part>& part, async::Action& action) override {
throw std::runtime_error("No writes here!!!");
}
};
ENDPOINT("GET", "multipart-stream", multipartStream) {
auto multipart = std::make_shared<MPStream>();
auto body = std::make_shared<oatpp::web::protocol::http::outgoing::MultipartBody>(
multipart,
"multipart/x-mixed-replace",
true /* flush parts */
);
return OutgoingResponse::createShared(Status::CODE_200, body);
}
Both oatpp::network::ServerConnectionProvider
and oatpp::network::ClientConnectionProvider
are now subclasses of a general oatpp::provider::Provider<data::stream::IOStream>
class.
Renamed methods:
getConnection()
--> get()
getConnectionAsync()
--> getAsync()
invalidateConnection()
--> invalidate()
This was done to unify providers' APIs and to have same API for all resource providers and resource pools.
Connection Providers and Connection Pools of the new ORM database adaptors are implemented based on the same functionality.
More info on ConnectionProvider changes see here - Changes in oatpp::network Namespace.
To simplify the integration of custom types with oatpp Object-Mapping framework the the "Type Interpretation" feature was introduced.
Let's say you have some struct that is not part of oatpp object-mapping framework.
struct VPoint {
v_int32 x;
v_int32 y;
v_int32 z;
};
To integrate it with oatpp object-mapping you can do the following:
namespace __class {
class PointClass;
}
/* Declare ObjectWrapper for your type */
/* Mapping-Enabled Point */
typedef oatpp::data::mapping::type::Primitive<VPoint, __class::PointClass> Point;
namespace __class {
/**
* Type info
*/
class PointClass {
private:
/**
* Type interpretation
*/
class Inter : public oatpp::Type::Interpretation<Point, oatpp::UnorderedFields<oatpp::Int32>> {
public:
oatpp::UnorderedFields<oatpp::Int32> interpret(const Point& value) const override {
return {{"x", value->x}, {"y", value->y}, {"z", value->z}};
}
Point reproduce(const oatpp::UnorderedFields<oatpp::Int32> map) const override {
return Point({map["x"], map["y"], map["z"]});
}
};
public:
static const oatpp::ClassId CLASS_ID;
static oatpp::Type* getType(){
static Type type(
CLASS_ID, nullptr, nullptr,
{
{"my-types", new Inter()} //<-- Add type interpretation
}
);
return &type;
}
};
const oatpp::ClassId PointClass::CLASS_ID("my-types::Point");
}
Now the "Point" struct can be serialized/deserialized with object mappers.
oatpp::parser::json::mapping::ObjectMapper mapper;
{
auto config = mapper.getSerializer()->getConfig();
config->enabledInterpretations = {"my-types"}; // Enable "my-types" for serializer
}
{
auto config = mapper.getDeserializer()->getConfig();
config->enabledInterpretations = {"my-types"}; // Enable "my-types" for deserializer
}
Point point ({1, 2, 3}); // Create mapping-enabled Point
auto json = mapper.writeToString(point); // Serialize Point
auto pointClone = mapper.readFromString<Point>(json); // Deserialize Point
The main feature of the 1.2.0
release is the new ORM Framework.
For details see - Object-Relational Mapping (ORM) framework
oatpp::network::server::SimpleTCPConnectionProvider
--> oatpp::network::tcp::server::ConnectionProvider
oatpp::network::client::SimpleTCPConnectionProvider
--> oatpp::network::tcp::client::ConnectionProvider
oatpp::network::server::ConnectionHandler
--> atpp::network::ConnectionHandler
oatpp::network::server::Server
--> oatpp::network::Server
oatpp::network::Connection
--> oatpp::network::tcp::Connection
oatpp::network::Address
oatpp::network::tcp::server::ConnectionProvider
oatpp::network::tcp::server::ConnectionProvider::createShared(
{"localhost", 8000} /* network::Address */
);
oatpp::network::tcp::server::ConnectionProvider::createShared(
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */
);
oatpp::network::tcp::server::ConnectionProvider::createShared(
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */,
true /* use extended connections */
);
oatpp::network::tcp::client::ConnectionProvider
oatpp::network::tcp::client::ConnectionProvider::createShared(
{"localhost", 8000} /* network::Address */
);
oatpp::network::tcp::client::ConnectionProvider::createShared(
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */
);
oatpp::network::tcp::client::ConnectionProvider::createShared(
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */,
true /* use extended connections */
);