rest_rpc icon indicating copy to clipboard operation
rest_rpc copied to clipboard

乱码

Open dftan-github opened this issue 1 year ago • 6 comments

我在win11 x64上写了个测试,发现subscribe响应时传过来的首字变成乱码,后面的正常,?? 而编译运行你们自带的example没有这个问题,unicode、非unicode、MSGPACK_NO_BOOST、console、mfc这些组合我都试了,都一样的问题

期待能得到回复,先谢了

注: vs2022 使用的是c++14 rest_rpc是3-28-23从github下载回来的 我是在同一个exe中开启的server及client

image

dftan-github avatar Mar 29 '23 02:03 dftan-github

我这周看一下这个问题,可能是最近的某个pr引入的问题。

qicosmos avatar Mar 29 '23 04:03 qicosmos

你的server 代码是什么样的?我测试example里面的test_sub1 看到订阅的数据是正常的。

// client
void test_sub1() {
  rpc_client client;
  client.enable_auto_reconnect();
  client.enable_auto_heartbeat();
  bool r = client.connect("127.0.0.1", 9000);
  if (!r) {
    return;
  }

  client.subscribe("key", [](string_view data) { 
    std::cout << data << "\n";
  });

std::string str;
std::cin>>str;
}

qicosmos avatar Apr 02 '23 01:04 qicosmos

你的server 代码是什么样的?我测试example里面的test_sub1 看到订阅的数据是正常的。

// client
void test_sub1() {
  rpc_client client;
  client.enable_auto_reconnect();
  client.enable_auto_heartbeat();
  bool r = client.connect("127.0.0.1", 9000);
  if (!r) {
    return;
  }

  client.subscribe("key", [](string_view data) { 
    std::cout << data << "\n";
  });

std::string str;
std::cin>>str;
}

这里发不了压缩包吗?想要把测试程序源码发过去给你看看

dftan-github avatar Apr 03 '23 22:04 dftan-github

全部相关代码如下 .h

class CMFCApplication2Dlg : public CDialogEx { rest_rpc::rpc_client mAIOClient; rpc_server aioSvr;// (9000, std::thread::hardware_concurrency()); std::thread* thdAIOSvr; HWND hwndSvr; // 构造 public: CMFCApplication2Dlg(CWnd* pParent = nullptr); // 标准构造函数 ~CMFCApplication2Dlg() { if (thdAIOSvr) delete thdAIOSvr; }

.cpp

CMFCApplication2Dlg::CMFCApplication2Dlg(CWnd* pParent /=nullptr/) : CDialogEx(IDD_MFCAPPLICATION2_DIALOG, pParent) , aioSvr(9000, std::thread::hardware_concurrency())

{ thdAIOSvr = nullptr; hwndSvr = NULL; m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }

BOOL CMFCApplication2Dlg::OnInitDialog() { CDialogEx::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
	BOOL bNameValid;
	CString strAboutMenu;
	bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
	ASSERT(bNameValid);
	if (!strAboutMenu.IsEmpty())
	{
		pSysMenu->AppendMenu(MF_SEPARATOR);
		pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
	}
}
thdAIOSvr=new std::thread([&] {

	aioSvr.register_handler("publish_by_token", [&](rpc_conn conn,
		std::string key,
		std::string token,
		std::string val) {
			aioSvr.publish_by_token(std::move(key), std::move(token), std::move(val));
		});

	aioSvr.register_handler("publish",
		[&](rpc_conn conn, std::string key,
			std::string token, std::string val) {
				aioSvr.publish(std::move(key), std::move(val));
		});
	aioSvr.set_network_err_callback(
		[](std::shared_ptr<connection> conn, std::string reason) {
			std::cout << "remote client address: " << conn->remote_address()
				<< " networking error, reason: " << reason << "\n";
		});

	aioSvr.run();

	});

// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE);			// 设置大图标
SetIcon(m_hIcon, FALSE);		// 设置小图标

// TODO: 在此添加额外的初始化代码
thdAIOSvr->detach();
mAIOClient.enable_auto_reconnect();
mAIOClient.enable_auto_heartbeat();

bool r = mAIOClient.connect("127.0.0.1", 9000);
mAIOClient.subscribe("test", [](string_view data) {
	std::cout << data << std::endl;
	int i;
	i = 0;
	});



return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

}

void CMFCApplication2Dlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码

if (mAIOClient.has_connected())
{
	mAIOClient.publish("test", "hello subscriber");
}
//CDialogEx::OnOK();

}

dftan-github avatar Apr 03 '23 22:04 dftan-github

subscribe 得到的数据需要解包一下:

client.subscribe("key", [](string_view data) { 
    std::cout << data << "\n";
  });

改成

client.subscribe("key", [](string_view data) {
      msgpack_codec codec;
      auto str = codec.unpack<std::string>(data.data(), data.size());
      std::cout << str << "\n";
  });

这样就没有乱码了,略有不便,后面我改一下,改成让框架自动去解包。

qicosmos avatar Apr 07 '23 03:04 qicosmos

訂閱得到的數據需要解包下一篇:

client.subscribe("key", [](string_view data) { 
    std::cout << data << "\n";
  });

改成

client.subscribe("key", [](string_view data) {
      msgpack_codec codec;
      auto str = codec.unpack<std::string>(data.data(), data.size());
      std::cout << str << "\n";
  });

這樣就沒有亂碼了,略有不便,後面我改一下,改成讓框架自動去解包。

按你的指引,成功解决了问题,谢啦

dftan-github avatar Apr 09 '23 10:04 dftan-github