Running an HTTP server
The program example_http_server.cpp provides a very simple HTTP server which serves one particular image. The image is rendered in the same way as previous examples such as A first image.
The example_http_server.cpp program uses a simple request handler that always serves a fixed image, independent of the requested URL. A response handler is installed to set the content type to image/jpeg. This is just done for illustration purposes; the content type could also be set directly by the request handler.
Note:
For a general introduction to the HTTP server, see HTTP server.
example_http_server.cpp
001 /****************************************************************************** 002 * © 1986, 2014 NVIDIA Corporation. All rights reserved. 003 *****************************************************************************/ 004 005 // examples/example_http_server.cpp 006 // 007 // Imports a scene file, renders the scene, and serves the image via the HTTP server 008 // 009 // The example expects the following command line arguments: 010 // 011 // example_rendering <scene_file> <mdl_path> <port> 012 // 013 // scene_file some scene file, e.g., main.mi 014 // mdl_path path to the MDL modules, e.g., iray-<version>/mdl 015 // port port for the HTTP server 016 017 #include <iostream> 018 019 #include <mi/neuraylib.h> 020 021 // Include code shared by all examples. 022 #include "example_shared.h" 023 // Include an implementation of IRender_target. 024 #include "example_render_target_simple.h" 025 026 // Simple request handler which always sends the buffer passed in the constructor 027 class Request_handler : public mi::base::Interface_implement<mi::http::IRequest_handler> 028 { 029 public: 030 // Constructor. Stores the passed buffer. 031 Request_handler( mi::base::Handle<mi::IBuffer> buffer) 032 { 033 m_buffer = buffer; 034 } 035 036 // Send buffer contents over the connection. 037 bool handle( mi::http::IConnection* connection) 038 { 039 connection->enqueue( m_buffer.get()); 040 return true; 041 } 042 private: 043 // The stored buffer 044 mi::base::Handle<mi::IBuffer> m_buffer; 045 }; 046 047 // Simple response handler which always sets the content type for JPG images 048 class Response_handler : public mi::base::Interface_implement<mi::http::IResponse_handler> 049 { 050 public: 051 void handle( mi::http::IConnection* connection) 052 { 053 mi::http::IResponse* iresponse( connection->get_response()); 054 iresponse->set_header( "Content-Type", "image/jpeg"); 055 } 056 }; 057 058 void configuration( mi::base::Handle<mi::neuraylib::INeuray> neuray, const char* mdl_path) 059 { 060 // Configure the neuray library. Here we set the search path for .mdl files. 061 mi::base::Handle<mi::neuraylib::IRendering_configuration> rendering_configuration( 062 neuray->get_api_component<mi::neuraylib::IRendering_configuration>()); 063 check_success( rendering_configuration.is_valid_interface()); 064 check_success( rendering_configuration->add_mdl_path( mdl_path) == 0); 065 066 // Load the FreeImage, Iray Photoreal, and .mi importer plugins. 067 mi::base::Handle<mi::neuraylib::IPlugin_configuration> plugin_configuration( 068 neuray->get_api_component<mi::neuraylib::IPlugin_configuration>()); 069 #ifndef MI_PLATFORM_WINDOWS 070 check_success( plugin_configuration->load_plugin_library( "freeimage.so") == 0); 071 check_success( plugin_configuration->load_plugin_library( "libiray.so") == 0); 072 check_success( plugin_configuration->load_plugin_library( "mi_importer.so") == 0); 073 #else 074 check_success( plugin_configuration->load_plugin_library( "freeimage.dll") == 0); 075 check_success( plugin_configuration->load_plugin_library( "libiray.dll") == 0); 076 check_success( plugin_configuration->load_plugin_library( "mi_importer.dll") == 0); 077 #endif 078 } 079 080 mi::base::Handle<mi::IBuffer> rendering( mi::base::Handle<mi::neuraylib::INeuray> neuray, 081 const char* scene_file) 082 { 083 // Get the database, the global scope, which is the root for all transactions, 084 // and create a transaction for importing the scene file and storing the scene. 085 mi::base::Handle<mi::neuraylib::IDatabase> database( 086 neuray->get_api_component<mi::neuraylib::IDatabase>()); 087 check_success( database.is_valid_interface()); 088 mi::base::Handle<mi::neuraylib::IScope> scope( 089 database->get_global_scope()); 090 mi::base::Handle<mi::neuraylib::ITransaction> transaction( 091 scope->create_transaction()); 092 check_success( transaction.is_valid_interface()); 093 094 // Import the scene file 095 mi::base::Handle<mi::neuraylib::IImport_api> import_api( 096 neuray->get_api_component<mi::neuraylib::IImport_api>()); 097 check_success( import_api.is_valid_interface()); 098 mi::base::Handle<const mi::IString> uri( import_api->convert_filename_to_uri( scene_file)); 099 mi::base::Handle<const mi::IImport_result> import_result( 100 import_api->import_elements( transaction.get(), uri->get_c_str())); 101 check_success( import_result->get_error_number() == 0); 102 103 // Create the scene object 104 mi::base::Handle<mi::neuraylib::IScene> scene( 105 transaction->create<mi::neuraylib::IScene>( "Scene")); 106 scene->set_rootgroup( import_result->get_rootgroup()); 107 scene->set_options( import_result->get_options()); 108 scene->set_camera_instance( import_result->get_camera_inst()); 109 transaction->store( scene.get(), "the_scene"); 110 111 // Create the render context using the Iray Photoreal render mode 112 scene = transaction->edit<mi::neuraylib::IScene>( "the_scene"); 113 mi::base::Handle<mi::neuraylib::IRender_context> render_context( 114 scene->create_render_context( transaction.get(), "iray")); 115 check_success( render_context.is_valid_interface()); 116 mi::base::Handle<mi::IString> scheduler_mode( transaction->create<mi::IString>()); 117 scheduler_mode->set_c_str( "batch"); 118 render_context->set_option( "scheduler_mode", scheduler_mode.get()); 119 scene = 0; 120 121 // Create the render target and render the scene 122 mi::base::Handle<mi::neuraylib::IImage_api> image_api( 123 neuray->get_api_component<mi::neuraylib::IImage_api>()); 124 mi::base::Handle<mi::neuraylib::IRender_target> render_target( 125 new Render_target( image_api.get(), "Color", 512, 384)); 126 check_success( render_context->render( transaction.get(), render_target.get(), 0) >= 0); 127 128 // Access the first canvas of the render target 129 mi::base::Handle<mi::neuraylib::ICanvas> canvas( render_target->get_canvas( 0)); 130 131 // Convert content of the canvas to an JPG image 132 mi::base::Handle<mi::IBuffer> buffer( 133 image_api->create_buffer_from_canvas( canvas.get(), "jpg", "Rgb", "100")); 134 135 transaction->commit(); 136 137 return buffer; 138 } 139 140 void run_http_server( mi::base::Handle<mi::neuraylib::INeuray> neuray, 141 mi::base::Handle<mi::IBuffer> buffer, 142 const char* port) 143 { 144 // Create a server instance 145 mi::base::Handle<mi::http::IFactory> http_factory( 146 neuray->get_api_component<mi::http::IFactory>()); 147 mi::base::Handle<mi::http::IServer> http_server( 148 http_factory->create_server()); 149 150 // Install our request and response handlers 151 mi::base::Handle<mi::http::IRequest_handler> request_handler( 152 new Request_handler( buffer)); 153 http_server->install( request_handler.get()); 154 mi::base::Handle<mi::http::IResponse_handler> response_handler( 155 new Response_handler()); 156 http_server->install( response_handler.get()); 157 158 // Assemble server address 159 const char* ip = "0.0.0.0:"; 160 char address[255]; 161 address[0] = '\0'; 162 strncat( address, ip, sizeof(address) - 1); 163 strncat( address, port, sizeof(address) - 1 - strlen(address)); 164 165 // Run server for fixed time interval 166 http_server->start( address); 167 sleep_seconds( 30); 168 http_server->shutdown(); 169 } 170 171 int main( int argc, char* argv[]) 172 { 173 // Collect command line parameters 174 if( argc != 4) { 175 std::cerr << "Usage: example_http_server <scene_file> <mdl_path> <port>" << std::endl; 176 keep_console_open(); 177 return EXIT_FAILURE; 178 } 179 const char* scene_file = argv[1]; 180 const char* mdl_path = argv[2]; 181 const char* port = argv[3]; 182 183 // Access the neuray library 184 mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray()); 185 check_success( neuray.is_valid_interface()); 186 187 // Configure the neuray library 188 configuration( neuray, mdl_path); 189 190 // Start the neuray library 191 check_success( neuray->start() == 0); 192 193 // Do the actual rendering 194 mi::base::Handle<mi::IBuffer> buffer = rendering( neuray, scene_file); 195 196 // Serve image via HTTP server on given port 197 run_http_server( neuray, buffer, port); 198 buffer = 0; 199 200 // Shut down the neuray library 201 check_success( neuray->shutdown() == 0); 202 neuray = 0; 203 204 // Unload the neuray library 205 check_success( unload()); 206 207 keep_console_open(); 208 return EXIT_SUCCESS; 209 }