首先就不介绍Libwebsockets了,这逼官方demo写的云里雾里的,很烦,我就简而意赅的说一下吧。
我把WebSockets封成了一个类。
static struct lws_protocols protocols[] = {
/* first protocol must always be HTTP handler */
{
"http-only", /* name */
callback_http,/* callback */
// sizeof (struct per_session_data__http),/* per_session_data_size */
sizeof(websockets), /* max frame size / rx buffer */
0
},
{ NULL, NULL, 0, 0 } /* terminator */
};//相当于websokets回调的注册,http-only指的是消息的类型,callback_http是回调函数的指针。
static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
if (wsi->protocol) {
if (reason == LWS_CALLBACK_RECEIVE) {
char *str = new char[len + 1];
memcpy(str, in, len);
str[len] = '\0';
if (wsi->protocol->per_session_data_size > 0)
{
//wsi->protocol->user;
websockets* ws_server = (websockets*)wsi->protocol->user;
ws_server->OnRequestComplete(str);
}
}
}
return 0;
}
这就是回调函数的基本类型,wsi->protocol->user是用户自己传入的数据,划重点。。。。。
#ifndef ws_server_h__
#define ws_server_h__
#include
#include
#include
#include
class websockets
{
public:
websockets();
virtual ~websockets();
public:
class Delegate
{
public:
virtual void OnWsMessage(std::string msg) = 0;
};
public:
static websockets* Get()
{
static websockets web_sockets;
return &web_sockets;
}
/
//在构造和析构的时候使用
void Attach(Delegate* delegate);
void DeAttach(Delegate* delegate);
void OnRequestComplete(char* msg);
//init 和 uninit必须在主线程使用
void Init(int port);
void UnInit();
//
bool startAccept(int port);
bool stopAccept();
static DWORD WINAPI AcceptRoutine(void* pVoid);
private:
int m_port;
HANDLE m_hRoutine;
public:
typedef std::list
DelegateList delegate_list_;
};
static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
if (wsi->protocol) {
if (reason == LWS_CALLBACK_RECEIVE) {
char *str = new char[len + 1];
memcpy(str, in, len);
str[len] = '\0';
if (wsi->protocol->per_session_data_size > 0)
{
//wsi->protocol->user;
websockets* ws_server = (websockets*)wsi->protocol->user;
ws_server->OnRequestComplete(str);
}
}
}
return 0;
}
static struct lws_protocols protocols[] = {
/* first protocol must always be HTTP handler */
{
"http-only", /* name */
callback_http,/* callback */
// sizeof (struct per_session_data__http),/* per_session_data_size */
sizeof(websockets), /* max frame size / rx buffer */
0
},
{ NULL, NULL, 0, 0 } /* terminator */
};
#endif
//根据单例模式设计的服务器模型。
#include “websockets.h”
websockets::websockets()
{
m_port = 0;
m_hRoutine = NULL;
}
websockets::~websockets()
{
}
bool websockets::startAccept(int port)
{
m_port = port;
m_hRoutine = CreateThread(NULL, 0, AcceptRoutine, this, 0, NULL);
if (m_hRoutine == NULL || m_hRoutine == INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}
bool websockets::stopAccept()
{
if (m_hRoutine) {
bool ret = TerminateThread(m_hRoutine, 0);
CloseHandle(m_hRoutine);
return ret;
}
return false;
}
//在构造和析构的时候使用
void websockets::Attach(Delegate* delegate) {
delegate_list_.push_back(delegate);
}
void websockets::DeAttach(Delegate* delegate) {
delegate_list_.remove(delegate);
}
void websockets::OnRequestComplete(char* msg) {
std::string ws_msg = msg;
DelegateList::iterator it = delegate_list_.begin();
for (; it != delegate_list_.end(); it++)
{
Delegate* center = static_cast
if (center)
center->OnWsMessage(ws_msg);
}
}
void websockets::Init(int port) {
if (m_port == 0) {
startAccept(port);
}
return;
}
void websockets::UnInit() {
stopAccept();
}
DWORD WINAPI websockets::AcceptRoutine(void* pVoid)
{
websockets* ctx = (websockets*)pVoid;
struct lws_context_creation_info info;//上下文对象的信息
struct lws_context *context;//上下文对象指针
int opts = 0;//本软件的额外功能选项
volatile int force_exit = 0;
unsigned int ms, oldms = 0;
int n = 0;
//设置info,填充info信息体
memset(&info, 0, sizeof(info));
info.port = ctx->m_port;
info.iface = NULL;
info.protocols = protocols;
info.extensions = NULL;
info.ssl_cert_filepath = NULL;
info.ssl_private_key_filepath = NULL;
info.ssl_ca_filepath = NULL;
info.gid = -1;
info.uid = -1;
info.options = opts;
info.ka_time = 0;
info.ka_probes = 0;
info.ka_interval = 0;
info.user = ctx;
protocols[0].user = pVoid;
//info.user = this;
context = lws_create_context(&info);//创建上下文对面,管理ws
if (context == NULL) {
return -1;
}
int ret = 0;
while (ret >= 0) {
ret = lws_service(context, 50);
}
lws_context_destroy(context);
return 0;
}
ok啦,大家就直接拿websockets::Get()用就可以啦,全局来一个又简单又方便