linux下的服務大多都是epoll,網上有很多都是requset-response型別的伺服器; 自己專案中有推送的需要,所以自己也做了個,另外我閱讀了epoll寫操作事件觸發機制感覺寫得很全,自己也測試過,寫了個server,與大家分享。
為了好濱示推送,我把它與qt專案結合了,qt只是為了產生推送的訊息,其它全為純c++**。epoll的監聽是乙個死迴圈,我定義了如下介面。
#ifndef loop_h
#define loop_h
class loop
protected:
virtual void _run() = 0;//迴圈函式
};#endif // loop_h
#ifndef epollloop_h
#define epollloop_h
#include "loop.h"
#include "epollstream.h"
#include #include #include class epollserver;
class epollloop : public loop
;#endif // epollloop_h
#include "epollloop.h"
#include #include #include #include #include "epollserver.h"
#include #include #include epollloop::epollloop()
void epollloop::_run() //啟動epll監聽執行緒函式,並與主線程分離
void epollloop::_initialize() //建立epoll控制代碼
_run();
}void epollloop::_epollthread()
qdebug() << "event fd count" << nfds;
for(int i = 0; i < nfds; i++)
epollstreamptr stream = _streams[fd];
if(events[i].events & epollin)
}if(events[i].events & epollout)}}
}int32_t epollloop::_accept(int32_t eventfd, int32_t listenfd) //通過map對映呼叫server介面,處理新連線,reactor模式的典型應用
}epollloop *epollloop::get()
epollloop::~epollloop()
void epollloop::addserver(int socket, epollserver *server));}
void epollloop::addstream(epollstreamptr stream)
void epollloop::writemsg(std::string &bytes, std::vectorfds) //通過epoll主動推送訊息,用於在客戶端沒有請求時
}else}}
}}int32_t epollloop::addepollevents(int32_t events, int32_t fd) //新增監聽事件
int32_t epollloop::modifyepollevents(int32_t events, int32_t fd) //更改乙個已存在事件的監聽事件
對於讀取操作:
(1) 當buffer由不可讀狀態變為可讀的時候,即由空變為不空的時候。
(2) 當有新資料到達時,即buffer中的待讀內容變多的時候。
(3) 當buffer中有資料可讀(即buffer不空)且使用者對相應fd進行epoll_mod in事件時。
對於寫操作:
(1) 當buffer由不可寫變為可寫的時候,即由滿狀態變為不滿狀態的時候。
(2) 當有舊資料被傳送走時,即buffer中待寫的內容變少得時候。
(3) 當buffer中有可寫空間(即buffer不滿)且使用者對相應fd進行epoll_mod out事件時。
以下為推送截圖
當初始化時,緩衝區為空可寫,會觸發乙個寫事件
以下為接收截圖
接收的話,我沒有做其它操作只是在ide裡面列印出來了。工程會在其它模組講完之後,上傳,有意向的朋友可以先裝好linux的qt我用的是qt5.9.3,按照要求qt5以上就可以了。
在這個例子中,客戶端連線的讀寫以及推送都是在epoll的執行緒中執行,之前用過多執行緒讀寫,但有競爭問題;還是選擇了這種,畢竟書上也是這樣的;另外,我們還需要對收到的客戶端訊息做業務處理如果是耗時操作,就要考慮執行緒池了,socket的讀寫放在乙個執行緒中不容易問題;處理可以放在其它執行緒中,。
使用Jpush 極光推送 實現推送功能
農曆猴年最後一篇文章,在寫前先寫一段話,我覺得挺好的,2017年要努力做到 學會忍耐,因為事已成現實自己無法改變 學會說不,因為做不到的事不要強求 學會適應,因為任何條件下都要生存 學會知而不言,因為言多必失 學會拿得起放得下,以為只要這樣才會能重新開始新的起點 做不了決定的時候,讓時間幫你決定,如...
使用Websocket實現訊息推送(上)
聯絡客服功能在專案中非常難避免。一般有以下三種實現方式 第一種方式,最low的。實現簡單。可是浪費使用者流量 另外一種方式,接入簡單,功能強大,可是可能須要一定的成本 比方付費 第三種方式,須要一定的開發成本 伺服器託管費用忽略 websocket一種在單個 tcp 連線上進行全雙工通訊的協議。we...
實現reentrantlock和讀寫鎖
1 可以手動實現乙個類似reentrantlock的工具,首先要維護乙個state的標誌,代表當前是否有執行緒已經使用資源。執行緒lock的時候,會用cas給state加1,其他執行緒檢測狀態。另外需要維護乙個等待佇列,爭奪不到資源的執行緒統一掛起 park 等執行緒unlock的時候,標誌減為0,...