微信小程式lianc++後臺
阿新 • • 發佈:2018-11-12
貼上微信小程式傳送http請求程式碼:
onsend: function(){
wx.request({
url: 'http://127.0.0.1:1000', //c++後臺ip、埠
data: {
x: '1' , //傳送到後臺欄位
y: '2'
},
header:{
"Content-Type":"application/json"
},
method:"POST", //傳送POST,若為GET則改為GET
success: function(res) { var data = res.data; console.log(data); } }); }
c++後臺程式碼借鑑boost官網的asio的http server 3地址並自己做了修改:
官網地址:http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html
修改程式碼:
1、request_parser.hpp:
// // request_parser.hpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef HTTP_SERVER3_REQUEST_PARSER_HPP #define HTTP_SERVER3_REQUEST_PARSER_HPP #include <boost/logic/tribool.hpp> #include <boost/tuple/tuple.hpp> namespace http { namespace server3 { struct request; /// Parser for incoming requests. class request_parser { public: /// Construct ready to parse the request method. request_parser(); /// Reset to initial parser state. void reset(); /// Parse some data. The tribool return value is true when a complete request /// has been parsed, false if the data is invalid, indeterminate when more /// data is required. The InputIterator return value indicates how much of the /// input has been consumed. template <typename InputIterator> boost::tuple<boost::tribool, InputIterator> parse(request& req, InputIterator begin, InputIterator end) { if(req.method=="POST") state_ = expecting_newline_4; //自己增加針對post請求資料一次性接收不完問題 while (begin != end) { boost::tribool result = consume(req, *begin++); if (state_ != none && (result || !result)){ //針對post請求做特殊處理 if(req.method=="POST"){ char c = *begin; if(c=='\0') break; state_ = expecting_newline_4; result = consume(req, *begin++); } } if (result || !result){ return boost::make_tuple(result, begin); } } boost::tribool result = boost::indeterminate; return boost::make_tuple(result, begin); } private: /// Handle the next character of input. boost::tribool consume(request& req, char input); /// Check if a byte is an HTTP character. static bool is_char(int c); /// Check if a byte is an HTTP control character. static bool is_ctl(int c); /// Check if a byte is defined as an HTTP tspecial character. static bool is_tspecial(int c); /// Check if a byte is a digit. static bool is_digit(int c); /// The current state of the parser. enum state { method_start, method, uri_start, uri, http_version_h, http_version_t_1, http_version_t_2, http_version_p, http_version_slash, http_version_major_start, http_version_major, http_version_minor_start, http_version_minor, expecting_newline_1, header_line_start, header_lws, header_name, space_before_header_value, header_value, expecting_newline_2, expecting_newline_3, expecting_newline_4,//針對post請求 none //針對post請求 } state_; }; } // namespace server3 } // namespace http #endif // HTTP_SERVER3_REQUEST_PARSER_HPP
2、
// // request_parser.cpp // ~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "request_parser.hpp" #include "request.hpp" namespace http { namespace server3 { request_parser::request_parser() : state_(method_start) { } void request_parser::reset() { state_ = method_start; } boost::tribool request_parser::consume(request& req, char input) { switch (state_) { case method_start: if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { return false; } else { state_ = method; req.method.push_back(input); return boost::indeterminate; } case method: if (input == ' ') { state_ = uri; return boost::indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { return false; } else { req.method.push_back(input); return boost::indeterminate; } case uri_start: if (is_ctl(input)) { return false; } else { state_ = uri; req.uri.push_back(input); return boost::indeterminate; } case uri: if (input == ' ') { state_ = http_version_h; return boost::indeterminate; } else if (is_ctl(input)) { return false; } else { req.uri.push_back(input); return boost::indeterminate; } case http_version_h: if (input == 'H') { state_ = http_version_t_1; return boost::indeterminate; } else { return false; } case http_version_t_1: if (input == 'T') { state_ = http_version_t_2; return boost::indeterminate; } else { return false; } case http_version_t_2: if (input == 'T') { state_ = http_version_p; return boost::indeterminate; } else { return false; } case http_version_p: if (input == 'P') { state_ = http_version_slash; return boost::indeterminate; } else { return false; } case http_version_slash: if (input == '/') { req.http_version_major = 0; req.http_version_minor = 0; state_ = http_version_major_start; return boost::indeterminate; } else { return false; } case http_version_major_start: if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; state_ = http_version_major; return boost::indeterminate; } else { return false; } case http_version_major: if (input == '.') { state_ = http_version_minor_start; return boost::indeterminate; } else if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; return boost::indeterminate; } else { return false; } case http_version_minor_start: if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; state_ = http_version_minor; return boost::indeterminate; } else { return false; } case http_version_minor: if (input == '\r') { state_ = expecting_newline_1; return boost::indeterminate; } else if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; return boost::indeterminate; } else { return false; } case expecting_newline_1: if (input == '\n') { state_ = header_line_start; return boost::indeterminate; } else { return false; } case header_line_start: if (input == '\r') { state_ = expecting_newline_3; return boost::indeterminate; } else if (!req.headers.empty() && (input == ' ' || input == '\t')) { state_ = header_lws; return boost::indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { return false; } else { req.headers.push_back(header()); req.headers.back().name.push_back(input); state_ = header_name; return boost::indeterminate; } case header_lws: if (input == '\r') { state_ = expecting_newline_2; return boost::indeterminate; } else if (input == ' ' || input == '\t') { return boost::indeterminate; } else if (is_ctl(input)) { return false; } else { state_ = header_value; req.headers.back().value.push_back(input); return boost::indeterminate; } case header_name: if (input == ':') { state_ = space_before_header_value; return boost::indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { return false; } else { req.headers.back().name.push_back(input); return boost::indeterminate; } case space_before_header_value: if (input == ' ') { state_ = header_value; return boost::indeterminate; } else { return false; } case header_value: if (input == '\r') { state_ = expecting_newline_2; return boost::indeterminate; } else if (is_ctl(input)) { return false; } else { req.headers.back().value.push_back(input); return boost::indeterminate; } case expecting_newline_2: if (input == '\n') { state_ = header_line_start; return boost::indeterminate; } else { return false; } case expecting_newline_3: return (input == '\n'); case expecting_newline_4: //針對post請求做處理 { req.post.push_back(input); if(input=='}') { state_ = none; //對post請求處理完成。 return true; } return boost::indeterminate; } default: return false; } } bool request_parser::is_char(int c) { return c >= 0 && c <= 127; } bool request_parser::is_ctl(int c) { return c >= 0 && c <= 31 || c == 127; }
bool request_parser::is_tspecial(int c)
{
switch (c)
{
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
return true;
default:
return false;
}
}
bool request_parser::is_digit(int c)
{
return c >= '0' && c <= '9';
}
} // namespace server3
} // namespace http
3、
3、針對request_handler類增加了自己處理客戶端請求函式,不用官方的
void request_handler::handle_request(const request& req)
{
if(req.method=="POST"){
//json解析
Json::Reader reader;
Json::Value jsonval;
if(!(reader.parse(req.post,jsonval)))
{
std::cerr << "json解析錯誤:" << req.post << std::endl;
return ;
}
std::string funcid = jsonval["x"].asString();
std::string content = jsonval["y"].asString();
std::cout << "收到客戶端請求:" <<req.post<< std::endl;
}else{
std::cout << "收到客戶端請求:" <<req.uri.substr(2,req.uri.length())<< std::endl;
std::string str = req.uri;
std::vector<std::string> vecSegTag;
boost::split(vecSegTag, str, boost::is_any_of(("/?&=")));
m_MapContent.clear();
for(int i = 2; i < vecSegTag.size() - 1; ){
m_MapContent.insert(std::pair<std::string, std::string>(vecSegTag[i], vecSegTag[i+1]));
i += 2;
}
}
}
4、connection類修改handle_read函式增加自己處理客戶的請求函式
void connection::handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
if (!e)
{
boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
request_, buffer_.data(), buffer_.data() + bytes_transferred);
buffer_.assign('\0');
if (result)
{
request_handler_.handle_request(request_);
//std::map<std::string,std::string> tmp = request_handler_.getRequestContent();
/* request_handler_.handle_request(request_, reply_);*/
// Fill out the reply to be sent to the client.
reply_.status = reply::ok;
char buf[512] = {"hello"}; //迴應客戶端資料
reply_.content.append(buf);
reply_.headers.resize(2);
reply_.headers[0].name = "Content-Length";
reply_.headers[0].value = boost::lexical_cast<std::string>(reply_.content.size());
reply_.headers[1].name = "Content-Type";
reply_.headers[1].value = mime_types::extension_to_type("");
boost::asio::async_write(socket_, reply_.to_buffers(),
strand_.wrap(
boost::bind(&connection::handle_write, shared_from_this(),
boost::asio::placeholders::error)));
}
else if (!result)
{
reply_ = reply::stock_reply(reply::bad_request);
boost::asio::async_write(socket_, reply_.to_buffers(),
strand_.wrap(
boost::bind(&connection::handle_write, shared_from_this(),
boost::asio::placeholders::error)));
}
else
{
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
boost::bind(&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
}
// If an error occurs then no new asynchronous operations are started. This
// means that all shared_ptr references to the connection object will
// disappear and the object will be destroyed automatically after this
// handler returns. The connection class's destructor closes the socket.
}
3、針對request_handler類增加了自己處理客戶端請求函式,不用官方的
void request_handler::handle_request(const request& req)
{
if(req.method=="POST"){
//json解析
Json::Reader reader;
Json::Value jsonval;
if(!(reader.parse(req.post,jsonval)))
{
std::cerr << "json解析錯誤:" << req.post << std::endl;
return ;
}
std::string funcid = jsonval["x"].asString();
std::string content = jsonval["y"].asString();
std::cout << "收到客戶端請求:" <<req.post<< std::endl;
}else{
std::cout << "收到客戶端請求:" <<req.uri.substr(2,req.uri.length())<< std::endl;
std::string str = req.uri;
std::vector<std::string> vecSegTag;
boost::split(vecSegTag, str, boost::is_any_of(("/?&=")));
m_MapContent.clear();
for(int i = 2; i < vecSegTag.size() - 1; ){
m_MapContent.insert(std::pair<std::string, std::string>(vecSegTag[i], vecSegTag[i+1]));
i += 2;
}
}
}