目前已经全部完成,并且取得了非常好的效果 。
使用 febird.RPC 的一个文件服务器代码:
// ifile.h
class FileObj : public SessionScope
{
public:
BEGIN_RPC_ADD_MF(FileObj)
RPC_ADD_MF(open)
RPC_ADD_MF(read)
RPC_ADD_MF(write)
RPC_ADD_MF(close)
END_RPC_ADD_MF()
RPC_DECLARE_MF(open, (const std::string& fname, const std::string& mode))
RPC_DECLARE_MF(read, (vector<byte>* buffer, uint32_t length))
RPC_DECLARE_MF(write, (const vector<byte>& buffer, uint32_t* length))
RPC_DECLARE_MF(close, ())
};
RPC_TYPEDEF_PTR(FileObj);
// file_client.cpp
#include <stdio.h>
#include <febird/rpc/client.h>
#include <febird/io/SocketStream.h>
using namespace std;
using namespace febird;
using namespace febird::rpc;
#include "../ifile.h"
int main(int argc, char** argv[])
{
#ifdef _WIN32
WSADATA information;
WSAStartup(MAKEWORD(2, 2), &information);
#endif
try {
auto_ptr<SocketStream> cs(ConnectSocket("127.0.0.1:8001"));
rpc_client<PortableDataInput, PortableDataOutput> client(cs.get());
FileObjPtr file;
client.create(file);
string fname = "test.txt";
vector<byte> buffer;
int ret = file->open(fname, "w+");
if (0 == ret)
{
printf("open file for write successed\n");
string txt = "Hello, world, this is a test file\n";
buffer.resize(txt.size());
std::copy(txt.begin(), txt.end(), buffer.begin());
uint32_t nWritten;
file->write(buffer, &nWritten);
printf("write=%d, written=%d\n", buffer.size(), nWritten);
file->close();
}
ret = file->open("test.txt", "r");
if (0 == ret)
{
printf("open file for read successed\n");
uint32_t nRead = buffer.size();
file->read(&buffer, nRead);
printf("read=%d, readed=%d\n", nRead, buffer.size());
string txt;
txt.resize(buffer.size());
std::copy(buffer.begin(), buffer.end(), txt.begin());
printf("readed text=%s\n", txt.c_str());
}
else
{
printf("open file for read failed\n");
}
}
catch (const std::exception& exp)
{
printf("exception: what=%s\n", exp.what());
}
#ifdef _WIN32
WSACleanup();
#endif
return 0;
}
// file_server.cpp
#include <stdio.h>
#include <febird/rpc/server.h>
#include <febird/io/SocketStream.h>
#include <iostream>
using namespace std;
using namespace febird;
using namespace febird::rpc;
#include "../ifile.h"
BEGIN_RPC_IMP_INTERFACE(FileObjImp, FileObj)
FileObjImp()
{
fp = 0;
}
~FileObjImp()
{
if (fp)
{
fclose(fp);
}
}
rpc_return_t open(const std::string& fname, const std::string& mode)
{
fp = fopen(fname.c_str(), mode.c_str());
if (0 == fp)
return errno;
return 0;
}
rpc_return_t read(vector<byte>* buffer, uint32_t length)
{
buffer->resize(length);
size_t nRead = fread(&*buffer->begin(), 1, length, fp);
buffer->resize(nRead);
return 0;
}
rpc_return_t write(const vector<byte>& buffer, uint32_t* length)
{
*length = fwrite(&*buffer.begin(), 1, buffer.size(), fp);
return 0;
}
rpc_return_t FileObj::close()
{
fclose(fp);
fp = 0;
return 0;
}
private:
FILE* fp;
END_RPC_IMP_INTERFACE()
int main(int argc, char** argv[])
{
#ifdef _WIN32
WSADATA information;
WSAStartup(MAKEWORD(2, 2), &information);
#endif
try {
SocketAcceptor acceptor("0.0.0.0:8001");
rpc_server<PortableDataInput, PortableDataOutput> server(&acceptor);
// FileObjImp will auto created by client call
RPC_SERVER_AUTO_CREATE(server, FileObjImp);
server.start();
}
catch (const std::exception& exp)
{
printf("exception: what=%s\n", exp.what());
}
#ifdef _WIN32
WSACleanup();
#endif
return 0;
}