111
This commit is contained in:
@@ -11,42 +11,149 @@
|
||||
#include <asio/basic_socket_streambuf.hpp>
|
||||
#include <iostream>
|
||||
|
||||
extern HSQUIRRELVM v;
|
||||
extern std::recursive_mutex SqMtx;
|
||||
|
||||
static SQInteger CreateHttp(HSQUIRRELVM v)
|
||||
{
|
||||
const SQChar *Host;
|
||||
sq_getstring(v, 2, &Host);
|
||||
const SQChar *Sevice;
|
||||
sq_getstring(v, 3, &Sevice);
|
||||
const SQChar *Service;
|
||||
sq_getstring(v, 3, &Service);
|
||||
const SQChar *Content;
|
||||
sq_getstring(v, 4, &Content);
|
||||
|
||||
asio::io_context ioContext;
|
||||
asio::ip::tcp::resolver resolver(ioContext);
|
||||
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(Host, Sevice);
|
||||
|
||||
asio::ip::tcp::socket socket(ioContext);
|
||||
asio::connect(socket, endpoints);
|
||||
|
||||
std::string request = std::string(Content);
|
||||
asio::write(socket, asio::buffer(request));
|
||||
|
||||
asio::streambuf response;
|
||||
asio::error_code error;
|
||||
asio::read(socket, response, error);
|
||||
|
||||
if (error != asio::error::eof)
|
||||
try
|
||||
{
|
||||
throw asio::system_error(error);
|
||||
sq_pushnull(v);
|
||||
}
|
||||
asio::io_context ioContext;
|
||||
asio::ip::tcp::resolver resolver(ioContext);
|
||||
auto endpoints = resolver.resolve(Host, Service);
|
||||
asio::ip::tcp::socket socket(ioContext);
|
||||
asio::connect(socket, endpoints);
|
||||
// 发送HTTP请求(假设Content包含完整请求)
|
||||
std::string request = Content;
|
||||
asio::write(socket, asio::buffer(request));
|
||||
// 读取响应(改进建议:解析Content-Length或分块传输)
|
||||
asio::streambuf response;
|
||||
asio::error_code error;
|
||||
while (asio::read(socket, response, asio::transfer_at_least(1), error))
|
||||
{
|
||||
}
|
||||
|
||||
std::istream responseStream(&response);
|
||||
std::ostringstream oss;
|
||||
oss << responseStream.rdbuf();
|
||||
sq_pushstring(v, oss.str().c_str(), -1);
|
||||
if (error && error != asio::error::eof)
|
||||
{
|
||||
throw asio::system_error(error);
|
||||
}
|
||||
// 将响应内容返回
|
||||
std::istream responseStream(&response);
|
||||
std::ostringstream oss;
|
||||
oss << responseStream.rdbuf();
|
||||
sq_pushstring(v, oss.str().c_str(), -1);
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
return sq_throwerror(v, e.what()); // 返回错误信息
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return sq_throwerror(v, _SC("Unknown error occurred"));
|
||||
}
|
||||
}
|
||||
|
||||
void handle_client(tcp::socket *socket, HSQOBJECT HttpServerObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 读取请求
|
||||
asio::streambuf request_buf;
|
||||
asio::read_until(*socket, request_buf, "\r\n\r\n");
|
||||
// 提取请求内容
|
||||
std::string request_data = asio::buffer_cast<const char *>(request_buf.data());
|
||||
|
||||
// 调用回调函数(需处理 Squirrel VM 上下文)
|
||||
std::cout << request_data << std::endl;
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushobject(v, HttpServerObject);
|
||||
sq_pushstring(v, _SC("Event"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{
|
||||
sq_pushobject(v, HttpServerObject);
|
||||
sq_pushuserpointer(v, socket);
|
||||
sq_pushstring(v, request_data.c_str(), -1);
|
||||
sq_call(v, 3, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 启动 HTTP 服务
|
||||
void start_server(const std::string &host, const std::string &port, HSQOBJECT HttpServerObject)
|
||||
{
|
||||
asio::io_context io_context;
|
||||
tcp::acceptor acceptor(io_context, tcp::endpoint(asio::ip::make_address(host), std::stoi(port)));
|
||||
std::cout << "Server listening on " << host << ":" << port << std::endl;
|
||||
while (true)
|
||||
{
|
||||
tcp::socket *socket = new tcp::socket(io_context);
|
||||
acceptor.accept(*socket);
|
||||
std::cout << "收到信息" << std::endl;
|
||||
// 传递 HttpServerObject 到 handle_client
|
||||
std::thread(handle_client, std::move(socket), HttpServerObject).detach();
|
||||
}
|
||||
}
|
||||
|
||||
static SQInteger CreateHttpServer(HSQUIRRELVM v)
|
||||
{
|
||||
const SQChar *host, *port;
|
||||
sq_getstring(v, 2, &host);
|
||||
sq_getstring(v, 3, &port);
|
||||
HSQOBJECT HttpServerObject;
|
||||
sq_getstackobj(v, 4, &HttpServerObject);
|
||||
// 必须增加一次引用一会记得删除 不然这个函数会被释放
|
||||
sq_addref(v, &HttpServerObject);
|
||||
try
|
||||
{
|
||||
std::thread server_thread(start_server, host, port, HttpServerObject);
|
||||
server_thread.detach();
|
||||
sq_pushbool(v, true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
sq_pushbool(v, false);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SQInteger HttpServerResponse_Write(HSQUIRRELVM v)
|
||||
{
|
||||
SQUserPointer P;
|
||||
sq_getuserpointer(v, 2, &P);
|
||||
tcp::socket *socket = (tcp::socket *)P;
|
||||
const SQChar *Content;
|
||||
sq_getstring(v, 3, &Content);
|
||||
try
|
||||
{
|
||||
std::string response = Content;
|
||||
asio::write(*socket, asio::buffer(response));
|
||||
socket->close();
|
||||
delete socket;
|
||||
return 0;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
socket->close();
|
||||
delete socket;
|
||||
return sq_throwerror(v, _SC("Unknown error occurred"));
|
||||
}
|
||||
}
|
||||
|
||||
static SQInteger register_Dio_func(HSQUIRRELVM v, SQFUNCTION f, const char *fname)
|
||||
{
|
||||
sq_pushroottable(v);
|
||||
@@ -60,4 +167,8 @@ static void RegisterDio(HSQUIRRELVM v)
|
||||
{
|
||||
// 创建Http
|
||||
register_Dio_func(v, CreateHttp, _SC("Sq_CreateHttp"));
|
||||
// 创建HttpServer
|
||||
register_Dio_func(v, CreateHttpServer, _SC("Sq_CreateHttpServer"));
|
||||
// 回应HttpServer响应体
|
||||
register_Dio_func(v, HttpServerResponse_Write, _SC("Sq_HttpServerResponse_Write"));
|
||||
}
|
||||
Reference in New Issue
Block a user