adj:调整工程结构。
This commit is contained in:
parent
c33e1f8f23
commit
64c9588315
12
.clangd
Normal file
12
.clangd
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Hover:
|
||||||
|
ShowAKA: Yes
|
||||||
|
Diagnostics:
|
||||||
|
UnusedIncludes: None # 禁用未使用头文件提示
|
||||||
|
Suppress: [
|
||||||
|
anon_type_definition, # 禁用匿名的typedef提示
|
||||||
|
unused-variable, # 禁用未使用变量提示
|
||||||
|
unused-function, # 禁用未使用函数提示
|
||||||
|
unused-includes, # 禁用未使用的头文件提示
|
||||||
|
]
|
||||||
|
ClangTidy:
|
||||||
|
Remove: misc-unused-alias-decls
|
115
.vscode/settings.json
vendored
115
.vscode/settings.json
vendored
@ -26,8 +26,6 @@
|
|||||||
},
|
},
|
||||||
"cmake.options.statusBarVisibility": "visible",
|
"cmake.options.statusBarVisibility": "visible",
|
||||||
"cmake.generator": "Ninja",
|
"cmake.generator": "Ninja",
|
||||||
"C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json",
|
|
||||||
"C_Cpp.default.cppStandard": "c++17",
|
|
||||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||||
"editor.inlayHints.enabled": "off",
|
"editor.inlayHints.enabled": "off",
|
||||||
"editor.unicodeHighlight.allowedLocales": {
|
"editor.unicodeHighlight.allowedLocales": {
|
||||||
@ -35,104 +33,17 @@
|
|||||||
"zh-hant": true,
|
"zh-hant": true,
|
||||||
"zh-hans": true
|
"zh-hans": true
|
||||||
},
|
},
|
||||||
"files.associations": {
|
"C_Cpp.intelliSenseEngine": "disabled",
|
||||||
"ostream": "cpp",
|
"clangd.arguments": [
|
||||||
"string": "cpp",
|
"--header-insertion=never",
|
||||||
"any": "cpp",
|
"--all-scopes-completion",
|
||||||
"array": "cpp",
|
"--completion-style=detailed",
|
||||||
"atomic": "cpp",
|
"--clang-tidy",
|
||||||
"bit": "cpp",
|
"-j=4",
|
||||||
"*.tcc": "cpp",
|
"--pch-storage=memory",
|
||||||
"cctype": "cpp",
|
"--compile-commands-dir=build",
|
||||||
"clocale": "cpp",
|
"--background-index",
|
||||||
"cmath": "cpp",
|
"--ranking-model=heuristics",
|
||||||
"codecvt": "cpp",
|
"--function-arg-placeholders=false"
|
||||||
"compare": "cpp",
|
],
|
||||||
"concepts": "cpp",
|
|
||||||
"cstdarg": "cpp",
|
|
||||||
"cstddef": "cpp",
|
|
||||||
"cstdint": "cpp",
|
|
||||||
"cstdio": "cpp",
|
|
||||||
"cstdlib": "cpp",
|
|
||||||
"cstring": "cpp",
|
|
||||||
"ctime": "cpp",
|
|
||||||
"cwchar": "cpp",
|
|
||||||
"cwctype": "cpp",
|
|
||||||
"deque": "cpp",
|
|
||||||
"forward_list": "cpp",
|
|
||||||
"map": "cpp",
|
|
||||||
"unordered_map": "cpp",
|
|
||||||
"vector": "cpp",
|
|
||||||
"exception": "cpp",
|
|
||||||
"algorithm": "cpp",
|
|
||||||
"functional": "cpp",
|
|
||||||
"iterator": "cpp",
|
|
||||||
"memory": "cpp",
|
|
||||||
"memory_resource": "cpp",
|
|
||||||
"numeric": "cpp",
|
|
||||||
"optional": "cpp",
|
|
||||||
"random": "cpp",
|
|
||||||
"ratio": "cpp",
|
|
||||||
"string_view": "cpp",
|
|
||||||
"system_error": "cpp",
|
|
||||||
"tuple": "cpp",
|
|
||||||
"type_traits": "cpp",
|
|
||||||
"utility": "cpp",
|
|
||||||
"initializer_list": "cpp",
|
|
||||||
"iomanip": "cpp",
|
|
||||||
"iosfwd": "cpp",
|
|
||||||
"iostream": "cpp",
|
|
||||||
"istream": "cpp",
|
|
||||||
"limits": "cpp",
|
|
||||||
"new": "cpp",
|
|
||||||
"numbers": "cpp",
|
|
||||||
"ranges": "cpp",
|
|
||||||
"span": "cpp",
|
|
||||||
"sstream": "cpp",
|
|
||||||
"stdexcept": "cpp",
|
|
||||||
"streambuf": "cpp",
|
|
||||||
"typeinfo": "cpp",
|
|
||||||
"valarray": "cpp",
|
|
||||||
"fstream": "cpp",
|
|
||||||
"chrono": "cpp",
|
|
||||||
"filesystem": "cpp",
|
|
||||||
"ios": "cpp",
|
|
||||||
"list": "cpp",
|
|
||||||
"locale": "cpp",
|
|
||||||
"xfacet": "cpp",
|
|
||||||
"xhash": "cpp",
|
|
||||||
"xiosbase": "cpp",
|
|
||||||
"xlocale": "cpp",
|
|
||||||
"xlocbuf": "cpp",
|
|
||||||
"xlocinfo": "cpp",
|
|
||||||
"xlocmes": "cpp",
|
|
||||||
"xlocmon": "cpp",
|
|
||||||
"xlocnum": "cpp",
|
|
||||||
"xloctime": "cpp",
|
|
||||||
"xmemory": "cpp",
|
|
||||||
"xmemory0": "cpp",
|
|
||||||
"xstddef": "cpp",
|
|
||||||
"xstring": "cpp",
|
|
||||||
"xtr1common": "cpp",
|
|
||||||
"xtree": "cpp",
|
|
||||||
"xutility": "cpp",
|
|
||||||
"condition_variable": "cpp",
|
|
||||||
"csignal": "cpp",
|
|
||||||
"future": "cpp",
|
|
||||||
"mutex": "cpp",
|
|
||||||
"shared_mutex": "cpp",
|
|
||||||
"thread": "cpp",
|
|
||||||
"variant": "cpp",
|
|
||||||
"*.ipp": "cpp",
|
|
||||||
"xthread": "cpp",
|
|
||||||
"bitset": "cpp",
|
|
||||||
"charconv": "cpp",
|
|
||||||
"coroutine": "cpp",
|
|
||||||
"format": "cpp",
|
|
||||||
"hash_map": "cpp",
|
|
||||||
"set": "cpp",
|
|
||||||
"source_location": "cpp",
|
|
||||||
"stop_token": "cpp",
|
|
||||||
"unordered_set": "cpp"
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -8,10 +8,6 @@ if (MSVC)
|
|||||||
add_compile_options(/utf-8)
|
add_compile_options(/utf-8)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows")
|
|
||||||
MESSAGE(STATUS "Add MinGW Param.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(-D_WIN32_WINNT=0x0601)
|
add_definitions(-D_WIN32_WINNT=0x0601)
|
||||||
|
|
||||||
set(CMAKE_DEBUG_POSTFIX "d")
|
set(CMAKE_DEBUG_POSTFIX "d")
|
||||||
@ -22,9 +18,7 @@ set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})
|
|||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}/)
|
||||||
|
|
||||||
include_directories(3rd)
|
include_directories(3rd)
|
||||||
find_package(CURL REQUIRED)
|
include_directories(.)
|
||||||
|
add_subdirectory(cexport)
|
||||||
add_executable(openai-api main.cxx zapi.h zapi.cxx jsondata.h jsondata.cxx handle.h handle.cxx server.h server.cxx)
|
add_subdirectory(server)
|
||||||
target_link_libraries(openai-api PRIVATE CURL::libcurl)
|
add_subdirectory(test)
|
||||||
|
|
||||||
add_executable(openai-api-test client_test.cxx)
|
|
||||||
|
10
cexport/CMakeLists.txt
Normal file
10
cexport/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(copenai LANGUAGES CXX)
|
||||||
|
|
||||||
|
add_library(copenai SHARED
|
||||||
|
cdllexport.h
|
||||||
|
cdllexport.cpp
|
||||||
|
../openaiclient.h
|
||||||
|
../openaiclient.cpp
|
||||||
|
)
|
60
cexport/cdllexport.cpp
Normal file
60
cexport/cdllexport.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "cdllexport.h"
|
||||||
|
|
||||||
|
#include <asio.hpp>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../openaiclient.h"
|
||||||
|
|
||||||
|
class CApiDllExport
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CApiDllExport();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void init_exchange(ExchangeData* ex);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<OpenAIClient> client;
|
||||||
|
static std::string server_ip;
|
||||||
|
static unsigned int port;
|
||||||
|
asio::io_context io_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<OpenAIClient> CApiDllExport::client = nullptr;
|
||||||
|
|
||||||
|
CApiDllExport::CApiDllExport()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CApiDllExport::init_exchange(ExchangeData* ex)
|
||||||
|
{
|
||||||
|
if (ex == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ex->content = nullptr;
|
||||||
|
ex->ck = 0;
|
||||||
|
ex->pk = 0;
|
||||||
|
ex->len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_api(const char* ip, unsigned int port)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ExchangeData* ask_openai(const char* content)
|
||||||
|
{
|
||||||
|
ExchangeData* ret = (ExchangeData*)malloc(sizeof(ExchangeData));
|
||||||
|
if (ret == nullptr) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
CApiDllExport::init_exchange(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_exchange_data(ExchangeData* data)
|
||||||
|
{
|
||||||
|
}
|
25
cexport/cdllexport.h
Normal file
25
cexport/cdllexport.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef CDLLEXPORT_H
|
||||||
|
#define CDLLEXPORT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ExchangeData {
|
||||||
|
char* content;
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int pk;
|
||||||
|
unsigned int ck;
|
||||||
|
} ExchangeData;
|
||||||
|
|
||||||
|
void init_api(const char* ip, unsigned int port);
|
||||||
|
|
||||||
|
ExchangeData* ask_openai(const char* content);
|
||||||
|
|
||||||
|
void free_exchange_data(ExchangeData* data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CDLLEXPORT_H
|
113
client_test.cxx
113
client_test.cxx
@ -1,113 +0,0 @@
|
|||||||
#include "communicate.hpp"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <asio.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
constexpr size_t g_BuffSize = 1024 * 10;
|
|
||||||
class Client
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Client(asio::io_context& io_context) : io_context_(io_context), socket_(io_context)
|
|
||||||
{
|
|
||||||
ip_ = "127.0.0.1";
|
|
||||||
port_ = "9999";
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool connect()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
asio::ip::tcp::resolver resolver(io_context_);
|
|
||||||
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(ip_, port_);
|
|
||||||
asio::connect(socket_, endpoints);
|
|
||||||
std::cout << "Connected to server " << ip_ << ":" << port_ << std::endl;
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
std::cerr << "Exception: " << ex.what() << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameData* post_deepseek(const std::string& text)
|
|
||||||
{
|
|
||||||
FrameData send;
|
|
||||||
send.type = FrameType::TYPE_REQUEST;
|
|
||||||
send.data = new char[text.size()];
|
|
||||||
send.len = text.size();
|
|
||||||
memcpy(send.data, text.c_str(), text.size());
|
|
||||||
|
|
||||||
char* send_data{};
|
|
||||||
int len{};
|
|
||||||
|
|
||||||
std::shared_ptr<int> deleter(new int(1), [send_data](int* p) {
|
|
||||||
delete p;
|
|
||||||
delete[] send_data;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!com_pack(&send, &send_data, len)) {
|
|
||||||
std::cerr << "com_pack error" << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto send_size = socket_.write_some(asio::buffer(send_data, len));
|
|
||||||
if (send_size != len) {
|
|
||||||
std::cerr << "send_size != text.size()" << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
size_t read_size = socket_.read_some(asio::buffer(tmp_buf_));
|
|
||||||
FrameData* ret = nullptr;
|
|
||||||
while (read_size > 0) {
|
|
||||||
buffer_.push(tmp_buf_.data(), read_size);
|
|
||||||
auto* frame = com_parse(buffer_);
|
|
||||||
if (frame) {
|
|
||||||
ret = frame;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
read_size = socket_.read_some(asio::buffer(tmp_buf_));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string ip_{};
|
|
||||||
std::string port_{};
|
|
||||||
asio::ip::tcp::socket socket_;
|
|
||||||
asio::io_context& io_context_;
|
|
||||||
CMutBuffer buffer_{};
|
|
||||||
std::array<char, g_BuffSize> tmp_buf_{};
|
|
||||||
};
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
system("chcp 65001");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
asio::io_context io_context;
|
|
||||||
Client client(io_context);
|
|
||||||
|
|
||||||
if (!client.connect()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::thread t([&io_context]() { io_context.run(); });
|
|
||||||
|
|
||||||
std::string text = "将【天文历】翻译为英文,直接给出结果。";
|
|
||||||
// std::string text = "This is a test.";
|
|
||||||
FrameData* frame = client.post_deepseek(text);
|
|
||||||
if (frame) {
|
|
||||||
std::cout << "type: " << frame->type << std::endl;
|
|
||||||
std::cout << "data: " << frame->data << std::endl;
|
|
||||||
std::cout << "len: " << frame->len << std::endl;
|
|
||||||
std::cout << "protk: " << frame->protk << std::endl;
|
|
||||||
std::cout << "coptk: " << frame->coptk << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete frame;
|
|
||||||
t.join();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -10,6 +10,8 @@
|
|||||||
#undef min
|
#undef min
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
constexpr size_t g_BuffSize = 1024 * 10;
|
||||||
|
|
||||||
enum FrameType : int16_t {
|
enum FrameType : int16_t {
|
||||||
TYPE_REQUEST = 0,
|
TYPE_REQUEST = 0,
|
||||||
TYPE_RESPONSE_SUCCESS,
|
TYPE_RESPONSE_SUCCESS,
|
||||||
@ -103,10 +105,10 @@ private:
|
|||||||
inline FrameData* com_parse(CMutBuffer& buffer)
|
inline FrameData* com_parse(CMutBuffer& buffer)
|
||||||
{
|
{
|
||||||
FrameData* r = nullptr;
|
FrameData* r = nullptr;
|
||||||
constexpr char header[] = {0xFF, 0xFE};
|
constexpr unsigned char header[] = {0xFF, 0xFE};
|
||||||
constexpr char tail[] = {0xFF, 0xFF};
|
constexpr unsigned char tail[] = {0xFF, 0xFF};
|
||||||
|
|
||||||
int find = buffer.index_of(header, sizeof(header));
|
int find = buffer.index_of((const char*)header, sizeof(header));
|
||||||
if (find < 0) {
|
if (find < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -163,8 +165,8 @@ inline bool com_pack(FrameData* data, char** out_buf, int& len)
|
|||||||
data->len = 0;
|
data->len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr char header[] = {0xFF, 0xFE};
|
constexpr unsigned char header[] = {0xFF, 0xFE};
|
||||||
constexpr char tail[] = {0xFF, 0xFF};
|
constexpr unsigned char tail[] = {0xFF, 0xFF};
|
||||||
|
|
||||||
len = sizeof(header) + sizeof(data->type) + sizeof(data->len) + sizeof(data->protk) + sizeof(data->coptk) + data->len +
|
len = sizeof(header) + sizeof(data->type) + sizeof(data->len) + sizeof(data->protk) + sizeof(data->coptk) + data->len +
|
||||||
sizeof(tail);
|
sizeof(tail);
|
||||||
|
68
openaiclient.cpp
Normal file
68
openaiclient.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "openaiclient.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
OpenAIClient::OpenAIClient(asio::io_context& io_context) : io_context_(io_context), socket_(io_context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenAIClient::connect(const std::string& ip, unsigned int port)
|
||||||
|
{
|
||||||
|
ip_ = ip;
|
||||||
|
port_ = std::to_string(port);
|
||||||
|
try {
|
||||||
|
asio::ip::tcp::resolver resolver(io_context_);
|
||||||
|
asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(ip_, port_);
|
||||||
|
asio::connect(socket_, endpoints);
|
||||||
|
std::cout << "Connected to server " << ip_ << ":" << port_ << std::endl;
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::cerr << "Exception: " << ex.what() << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameData* OpenAIClient::ask_openai(const std::string& text)
|
||||||
|
{
|
||||||
|
FrameData send;
|
||||||
|
send.type = FrameType::TYPE_REQUEST;
|
||||||
|
send.data = new char[text.size()];
|
||||||
|
send.len = text.size();
|
||||||
|
memcpy(send.data, text.c_str(), text.size());
|
||||||
|
|
||||||
|
char* send_data{};
|
||||||
|
int len{};
|
||||||
|
|
||||||
|
std::shared_ptr<int> deleter(new int(1), [send_data](int* p) {
|
||||||
|
delete p;
|
||||||
|
delete[] send_data;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!com_pack(&send, &send_data, len)) {
|
||||||
|
std::cerr << "com_pack error" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto send_size = socket_.write_some(asio::buffer(send_data, len));
|
||||||
|
if (send_size != len) {
|
||||||
|
std::cerr << "send_size != text.size()" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
size_t read_size = socket_.read_some(asio::buffer(tmp_buf_));
|
||||||
|
FrameData* ret = nullptr;
|
||||||
|
while (read_size > 0) {
|
||||||
|
buffer_.push(tmp_buf_.data(), read_size);
|
||||||
|
auto* frame = com_parse(buffer_);
|
||||||
|
if (frame) {
|
||||||
|
ret = frame;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
read_size = socket_.read_some(asio::buffer(tmp_buf_));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenAIClient::disconnect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
26
openaiclient.h
Normal file
26
openaiclient.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef OPENAICLIENT_H
|
||||||
|
#define OPENAICLIENT_H
|
||||||
|
|
||||||
|
#include <asio.hpp>
|
||||||
|
#include <communicate.hpp>
|
||||||
|
|
||||||
|
class OpenAIClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenAIClient(asio::io_context& io_context);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool connect(const std::string& ip, unsigned int port);
|
||||||
|
FrameData* ask_openai(const std::string& text);
|
||||||
|
void disconnect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string ip_{};
|
||||||
|
std::string port_{};
|
||||||
|
asio::ip::tcp::socket socket_;
|
||||||
|
asio::io_context& io_context_;
|
||||||
|
CMutBuffer buffer_{};
|
||||||
|
std::array<char, g_BuffSize> tmp_buf_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OPENAICLIENT_H
|
21
server/CMakeLists.txt
Normal file
21
server/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(openai-server LANGUAGES CXX)
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
find_package(CURL REQUIRED)
|
||||||
|
|
||||||
|
set(SERVER_SOURCES
|
||||||
|
zapi.h
|
||||||
|
zapi.cxx
|
||||||
|
jsondata.h
|
||||||
|
jsondata.cxx
|
||||||
|
server.h
|
||||||
|
server.cxx
|
||||||
|
config.h
|
||||||
|
config.cxx
|
||||||
|
main.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(openai-server ${SERVER_SOURCES})
|
||||||
|
target_link_libraries(openai-server PRIVATE CURL::libcurl)
|
@ -1,12 +1,9 @@
|
|||||||
#include "handle.h"
|
#include "config.h"
|
||||||
#include <SimpleIni.h>
|
|
||||||
#include <cctype>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <random>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
bool CConfig::parse_config(ConfigInfo& config, const std::string& config_path)
|
#include <SimpleIni.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
bool ConfigSet::parse_config(Configuration& config, const std::string& config_path)
|
||||||
{
|
{
|
||||||
CSimpleIniA ini_handle{};
|
CSimpleIniA ini_handle{};
|
||||||
SI_Error ret = ini_handle.LoadFile(config_path.c_str());
|
SI_Error ret = ini_handle.LoadFile(config_path.c_str());
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct ConfigInfo {
|
struct Configuration {
|
||||||
std::string api_env_key;
|
std::string api_env_key;
|
||||||
std::string base_url;
|
std::string base_url;
|
||||||
std::string user_name;
|
std::string user_name;
|
||||||
@ -11,11 +11,11 @@ struct ConfigInfo {
|
|||||||
long max_tokens{};
|
long max_tokens{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class CConfig
|
class ConfigSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CConfig() = default;
|
ConfigSet() = default;
|
||||||
~CConfig() = default;
|
~ConfigSet() = default;
|
||||||
public:
|
public:
|
||||||
static bool parse_config(ConfigInfo& config, const std::string& config_path = "");
|
static bool parse_config(Configuration& config, const std::string& config_path = "");
|
||||||
};
|
};
|
@ -1,5 +1,6 @@
|
|||||||
#include "jsondata.h"
|
#include "jsondata.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
CJsonOper::CJsonOper(const std::string& user_name, const std::string& model, const std::string& assistant_name)
|
CJsonOper::CJsonOper(const std::string& user_name, const std::string& model, const std::string& assistant_name)
|
||||||
: user_(user_name), model_(model), assistant_(assistant_name)
|
: user_(user_name), model_(model), assistant_(assistant_name)
|
||||||
@ -30,35 +31,6 @@ std::vector<std::string> CJsonOper::split(const std::string& input, const std::s
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CJsonOper::multi_format_reuqest(const std::string& content, size_t per_sec_size)
|
|
||||||
{
|
|
||||||
std::string model = model_;
|
|
||||||
std::string role = user_;
|
|
||||||
nlohmann::json json_data;
|
|
||||||
json_data["model"] = model;
|
|
||||||
|
|
||||||
std::vector<nlohmann::json> messages;
|
|
||||||
size_t s = 0;
|
|
||||||
while (s < content.size()) {
|
|
||||||
size_t i = 0;
|
|
||||||
size_t t = 0;
|
|
||||||
while (i < per_sec_size && s + i < content.size()) {
|
|
||||||
t = get_u8_len(content[s + i]);
|
|
||||||
if (t == 0) {
|
|
||||||
std::cerr << "invalid codec!!!" << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
i += t;
|
|
||||||
}
|
|
||||||
std::string part = content.substr(s, i);
|
|
||||||
messages.push_back({{"role", role}, {"content", "\n附加数据:\n" + part}});
|
|
||||||
s += i;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_data["messages"] = messages;
|
|
||||||
return json_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
Message CJsonOper::parse(const std::string& data)
|
Message CJsonOper::parse(const std::string& data)
|
||||||
{
|
{
|
||||||
Message re;
|
Message re;
|
||||||
@ -147,39 +119,3 @@ std::string CJsonOper::trim(const std::string& input)
|
|||||||
return input.substr(start, end - start + 1);
|
return input.substr(start, end - start + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CJsonOper::get_all_dir_content(const std::string& dir, const std::string& types)
|
|
||||||
{
|
|
||||||
auto vec = split(types, ",");
|
|
||||||
std::vector<std::string> t;
|
|
||||||
for (const auto& item : vec) {
|
|
||||||
auto c = trim(item);
|
|
||||||
if (c.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
t.push_back("." + item);
|
|
||||||
std::cout << "use type:" << item << std::endl;
|
|
||||||
}
|
|
||||||
std::vector<std::string> task;
|
|
||||||
for (const auto& entry : fs::directory_iterator(dir)) {
|
|
||||||
if (!fs::is_regular_file(entry)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto exten = entry.path().filename().extension().string();
|
|
||||||
if (std::find(t.begin(), t.end(), exten) != t.end()) {
|
|
||||||
std::cout << "Parse:" << entry.path().string() << std::endl;
|
|
||||||
task.push_back(entry.path().string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 提取内容
|
|
||||||
std::string content;
|
|
||||||
for (const auto& item : task) {
|
|
||||||
std::string one;
|
|
||||||
if (read_txt(item, one)) {
|
|
||||||
content.append("\n\n" + one);
|
|
||||||
} else {
|
|
||||||
std::cerr << "Can't read file: " << item << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
@ -1,10 +1,7 @@
|
|||||||
#ifndef JSON_DATA
|
#ifndef JSON_DATA
|
||||||
#define JSON_DATA
|
#define JSON_DATA
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -27,13 +24,11 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
std::string format_request(const std::string& content);
|
std::string format_request(const std::string& content);
|
||||||
std::string multi_format_reuqest(const std::string& content, size_t per_sec_size);
|
|
||||||
Message parse(const std::string& data);
|
Message parse(const std::string& data);
|
||||||
static bool save_md(const std::string& data, const std::string& id);
|
static bool save_md(const std::string& data, const std::string& id);
|
||||||
static bool read_txt(const std::string& path, std::string& out);
|
static bool read_txt(const std::string& path, std::string& out);
|
||||||
static std::vector<std::string> split(const std::string& input, const std::string& delimiter);
|
static std::vector<std::string> split(const std::string& input, const std::string& delimiter);
|
||||||
static size_t get_u8_len(unsigned char ch);
|
static size_t get_u8_len(unsigned char ch);
|
||||||
static std::string get_all_dir_content(const std::string& dir, const std::string& types);
|
|
||||||
static std::string trim(const std::string& input);
|
static std::string trim(const std::string& input);
|
||||||
|
|
||||||
private:
|
private:
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#include "handle.h"
|
#include "config.h"
|
||||||
#include "jsondata.h"
|
#include "jsondata.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "zapi.h"
|
#include "zapi.h"
|
||||||
@ -42,8 +42,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
int port = std::stoi(argv[1]);
|
int port = std::stoi(argv[1]);
|
||||||
|
|
||||||
ConfigInfo config;
|
Configuration config;
|
||||||
if (!CConfig::parse_config(config, "openai.ini")) {
|
if (!ConfigSet::parse_config(config, "openai.ini")) {
|
||||||
std::cerr << "parse config failed." << std::endl;
|
std::cerr << "parse config failed." << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
@ -1,7 +1,8 @@
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "util.hpp"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
Server::Server(asio::io_context& io_context, short port) : io_context_(io_context), acceptor_(io_context)
|
Server::Server(asio::io_context& io_context, short port) : io_context_(io_context), acceptor_(io_context)
|
||||||
{
|
{
|
||||||
port_ = port;
|
port_ = port;
|
||||||
@ -16,11 +17,7 @@ Server::~Server()
|
|||||||
|
|
||||||
void Server::print_exception(const std::exception& e)
|
void Server::print_exception(const std::exception& e)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
std::cerr << ansi_to_u8(e.what()) << '\n';
|
|
||||||
#else
|
|
||||||
std::cerr << e.what() << '\n';
|
std::cerr << e.what() << '\n';
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::start()
|
void Server::start()
|
||||||
@ -61,7 +58,8 @@ void Server::do_accept()
|
|||||||
std::string client_key = endpoint.address().to_string() + ":" + std::to_string(endpoint.port());
|
std::string client_key = endpoint.address().to_string() + ":" + std::to_string(endpoint.port());
|
||||||
std::unique_lock<std::mutex> lock(cli_mutex_);
|
std::unique_lock<std::mutex> lock(cli_mutex_);
|
||||||
client_map_[client_key] = std::make_shared<ClientCache>();
|
client_map_[client_key] = std::make_shared<ClientCache>();
|
||||||
clients_.insert(std::make_pair(socket->remote_endpoint().address().to_string(),
|
clients_.insert(
|
||||||
|
std::make_pair(socket->remote_endpoint().address().to_string(),
|
||||||
std::thread([this, socket, client_key]() { th_client(socket, client_key); })));
|
std::thread([this, socket, client_key]() { th_client(socket, client_key); })));
|
||||||
}
|
}
|
||||||
|
|
@ -1,15 +1,14 @@
|
|||||||
#ifndef SERVER_H
|
#ifndef SERVER_H
|
||||||
#define SERVER_H
|
#define SERVER_H
|
||||||
|
|
||||||
#include "communicate.hpp"
|
|
||||||
#include "handle.h"
|
|
||||||
#include "jsondata.h"
|
|
||||||
#include "zapi.h"
|
|
||||||
#include <asio.hpp>
|
#include <asio.hpp>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
constexpr size_t g_BuffSize = 1024 * 10;
|
#include "communicate.hpp"
|
||||||
|
#include "jsondata.h"
|
||||||
|
#include "zapi.h"
|
||||||
|
|
||||||
struct ClientCache {
|
struct ClientCache {
|
||||||
std::array<char, g_BuffSize> tmp_buf_{};
|
std::array<char, g_BuffSize> tmp_buf_{};
|
||||||
CMutBuffer buffer_{};
|
CMutBuffer buffer_{};
|
||||||
@ -28,6 +27,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
void set_worker(std::shared_ptr<COpenAI> worker, std::shared_ptr<CJsonOper> json);
|
void set_worker(std::shared_ptr<COpenAI> worker, std::shared_ptr<CJsonOper> json);
|
||||||
void set_token(long tokens);
|
void set_token(long tokens);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void do_accept();
|
void do_accept();
|
||||||
void th_client(const std::shared_ptr<asio::ip::tcp::socket>& socket, const std::string& client_key);
|
void th_client(const std::shared_ptr<asio::ip::tcp::socket>& socket, const std::string& client_key);
|
6
test/CMakeLists.txt
Normal file
6
test/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(openai-test LANGUAGES CXX)
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
add_executable(openai-test client_test.cxx ../openaiclient.cpp)
|
39
test/client_test.cxx
Normal file
39
test/client_test.cxx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include <asio.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "../openaiclient.h"
|
||||||
|
#include "communicate.hpp"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
system("chcp 65001");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
asio::io_context io_context;
|
||||||
|
OpenAIClient client(io_context);
|
||||||
|
|
||||||
|
if (!client.connect("127.0.0.1", 9999)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread t([&io_context]() { io_context.run(); });
|
||||||
|
|
||||||
|
std::string text = "将【天文历】翻译为英文,直接给出结果。";
|
||||||
|
// std::string text = "This is a test.";
|
||||||
|
FrameData* frame = client.ask_openai(text);
|
||||||
|
if (frame) {
|
||||||
|
std::cout << "type: " << frame->type << std::endl;
|
||||||
|
std::cout << "data: " << frame->data << std::endl;
|
||||||
|
std::cout << "len: " << frame->len << std::endl;
|
||||||
|
std::cout << "protk: " << frame->protk << std::endl;
|
||||||
|
std::cout << "coptk: " << frame->coptk << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete frame;
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
31
util.hpp
31
util.hpp
@ -1,31 +0,0 @@
|
|||||||
#ifndef UTIL_HPP
|
|
||||||
#define UTIL_HPP
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
std::string ansi_to_u8(const std::string& str)
|
|
||||||
{
|
|
||||||
int wideCharLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);
|
|
||||||
if (wideCharLen <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::wstring wideStr(wideCharLen, L'\0');
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, &wideStr[0], wideCharLen);
|
|
||||||
|
|
||||||
int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
|
||||||
if (utf8Len <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::string utf8Str(utf8Len, '\0');
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, &utf8Str[0], utf8Len, nullptr, nullptr);
|
|
||||||
|
|
||||||
utf8Str.resize(utf8Len - 1);
|
|
||||||
return utf8Str;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // UTIL_HPP
|
|
Loading…
x
Reference in New Issue
Block a user