DP_S/include/SqrReg_Dio.hpp

174 lines
5.2 KiB
C++
Raw Normal View History

2024-10-23 19:53:15 +08:00
#pragma once
#include "squirrel.h"
#include "sqstdaux.h"
#include "sqstdblob.h"
#include "sqstdio.h"
#include "sqstdmath.h"
#include "sqstdstring.h"
#include "sqstdsystem.h"
#include <asio.hpp>
#include <asio/ssl.hpp>
#include <asio/basic_socket_streambuf.hpp>
#include <iostream>
2025-03-27 20:24:19 +08:00
extern HSQUIRRELVM v;
extern std::recursive_mutex SqMtx;
2024-10-23 19:53:15 +08:00
static SQInteger CreateHttp(HSQUIRRELVM v)
{
const SQChar *Host;
sq_getstring(v, 2, &Host);
2025-03-27 20:24:19 +08:00
const SQChar *Service;
sq_getstring(v, 3, &Service);
2024-10-23 19:53:15 +08:00
const SQChar *Content;
sq_getstring(v, 4, &Content);
2025-03-27 20:24:19 +08:00
try
{
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))
{
}
2024-10-23 19:53:15 +08:00
2025-03-27 20:24:19 +08:00
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"));
}
}
2024-10-23 19:53:15 +08:00
2025-03-27 20:24:19 +08:00
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());
2024-10-23 19:53:15 +08:00
2025-03-27 20:24:19 +08:00
// 调用回调函数(需处理 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;
}
}
2024-10-23 19:53:15 +08:00
2025-03-27 20:24:19 +08:00
// 启动 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)
2024-10-23 19:53:15 +08:00
{
2025-03-27 20:24:19 +08:00
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();
2024-10-23 19:53:15 +08:00
}
2025-03-27 20:24:19 +08:00
}
2024-10-23 19:53:15 +08:00
2025-03-27 20:24:19 +08:00
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);
}
2024-10-23 19:53:15 +08:00
return 1;
}
2025-03-27 20:24:19 +08:00
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"));
}
}
2024-10-23 19:53:15 +08:00
static SQInteger register_Dio_func(HSQUIRRELVM v, SQFUNCTION f, const char *fname)
{
sq_pushroottable(v);
sq_pushstring(v, fname, -1);
sq_newclosure(v, f, 0); // create a new function
sq_newslot(v, -3, SQFalse);
sq_pop(v, 1); // pops the root table
}
static void RegisterDio(HSQUIRRELVM v)
{
// 创建Http
register_Dio_func(v, CreateHttp, _SC("Sq_CreateHttp"));
2025-03-27 20:24:19 +08:00
// 创建HttpServer
register_Dio_func(v, CreateHttpServer, _SC("Sq_CreateHttpServer"));
// 回应HttpServer响应体
register_Dio_func(v, HttpServerResponse_Write, _SC("Sq_HttpServerResponse_Write"));
2024-10-23 19:53:15 +08:00
}