libwebsocket demo以及遇到的坑。

烟波--钓徒發表於2024-08-29

借鑑的 https://blog.csdn.net/qq_19004627/article/details/88737411

坑1:openssl報錯:ip address mismatch(preverify_ok=0;err=64;depth=0),不確定是不是自己生成的證書在無網情況下是不是不可用(開發電腦無法連網際網路),暫時遮蔽了openssl相關的程式碼。

坑2:這個文章的client的程式碼中的傳送程式碼有中文“你好”,導致伺服器解析異常,進而斷鏈(這個問題,困擾了我幾乎一整天)。暫時修改成非中文,如果一定要中文,需要轉utf-8。

坑3:伺服器的回顯程式碼可以做下最佳化。如下所示,當data->len非零時再傳輸。

case LWS_CALLBACK_SERVER_WRITEABLE:   // 當此連線可寫時
	{
		if (data->len != 0)
		{
			lws_write(wsi, &data->buf[LWS_PRE], data->len, LWS_WRITE_TEXT);
			data->len = 0;
		}
	} 

坑4:接收字串列印亂碼(直接列印in),可以在長度後面增加\0。

case LWS_CALLBACK_RECEIVE:           // 當接收到客戶端發來的幀以後
										 // 判斷是否最後一幀
		data->fin = lws_is_final_fragment(wsi);
		// 判斷是否二進位制訊息
		data->bin = lws_frame_is_binary(wsi);
		// 對伺服器的接收端進行流量控制,如果來不及處理,可以控制之
		// 下面的呼叫禁止在此連線上接收資料
		//lws_rx_flow_control(wsi, 0);
		// 業務處理部分,為了實現Echo伺服器,把客戶端資料儲存起來
		memcpy(&data->buf[LWS_PRE], in, len);
		data->len = len;
		data->buf[LWS_PRE + data->len] = 0;
		lwsl_notice("recvied message:%s,len=%d\n", (char*)&data->buf[LWS_PRE], data->len);

		// 需要給客戶端應答時,觸發一次寫回撥
		lws_callback_on_writable(wsi);
		break;

  

其他今天搜尋了一天的資料的心得:

1、lws_write前面一定要預留LWS_PRE的空間,給lws內部使用,否則會崩潰。

2、如果報文很長,需要分片,需要判斷lws_is_final_fragment,可以使用類似下面的程式碼:

case LWS_CALLBACK_RECEIVE:
 {
     Client * const client = (Client *)user;
     const size_t remaining = lws_remaining_packet_payload(wsi);
 
     if (!remaining && lws_is_final_fragment(wsi)) {
         if (client->HasFragments()) {
             client->AppendMessageFragment(in, len, 0);
             in = (void *)client->GetMessage();
             len = client->GetMessageLength();
         }
 
         client->ProcessMessage((char *)in, len, wsi);
         client->ResetMessage();
     } else
         client->AppendMessageFragment(in, len, remaining);
 }
 break;

3、客戶端支援多連線到不同伺服器,需要開多個執行緒去處理。

其他的一些可以參考https://blog.csdn.net/yetyongjin/article/details/131082375

相關文章