可以由drogon_ctl
工具快速生成WebSocketController
的源文件,命令格式如下:
假设我们要通过websocket实现一个简单的回声功能,即服务端只是简单的把客户端发来的消息再发回去,通过drogon_ctl
创建WebSocketController
的实现类EchoWebsock,如下:
drogon_ctl create controller -w EchoWebsock
#include "EchoWebsock.h"
void EchoWebsock::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr,std::string &&message)
{
//write your application logic here
}
void EchoWebsock::handleNewConnection(const HttpRequestPtr &req,const WebSocketConnectionPtr &wsConnPtr)
{
//write your application logic here
}
void EchoWebsock::handleConnectionClosed(const WebSocketConnectionPtr &wsConnPtr)
{
//write your application logic here
}
编辑后内容如下:
//EchoWebsock.cc
void EchoWebsock::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr,std::string &&message)
{
//write your application logic here
wsConnPtr->send(message);
}
void EchoWebsock::handleNewConnection(const HttpRequestPtr &req,const WebSocketConnectionPtr &wsConnPtr)
{
//write your application logic here
}
void EchoWebsock::handleConnectionClosed(const WebSocketConnectionPtr &wsConnPtr)
{
//write your application logic here
}
首先,在这个例子中,通过WS_PATH_ADD
宏把这个控制器注册到了/echo
路径上,WS_PATH_ADD
宏的用法跟之前介绍的其他控制器的宏类似,也可以注册路径并且附带若干过滤器Filter。由于websocket在框架中单独处理,所以它可以和前两种控制器的路径重复而不会相互影响。
注意:和通常的HTTP协议一样,http的websocket可以被旁路还原,如果需要安全保障,应由https提供加密功能,当然,用户自己在服务端和客户端完成加密和解密也是可以的,只是https更方便,底层都由drogon处理,用户只需关心业务逻辑。
用户自定义的WebSocketController
类继承自drogon::WebSocketController
类模板,模板参数是子类类型,用户需自己实现如下三个虚函数来对websocket的建立、关闭和消息进行处理:
- handleNewConnection在websocket建立之后被调用,req是客户端发来的建立请求,这时候框架已经返回了response,用户可以做的是通过req获得一些额外信息,比如token之类。wsConn是这个websocket对象的智能指针,常用的接口后面再谈。
- handleNewMessage在websocket收到新的消息之后被调用,消息存储在message变量里,注意这个message是完整的消息净荷,框架已经做完了消息的解封包和解码等工作,用户直接处理消息本身即可。
- handleConnectionClosed在websocket连接关闭之后调用,用户可以做一些收尾工作。
WebSocketConnection
WebSocketConnection对象常用接口如下:
//发送websocket消息,消息的编码和封包都由框架负责,这里直接发送消息的净荷
void send(const std::string &msg);
//本websocket的本端和远端地址
const trantor::InetAddress &localAddr() const;
const trantor::InetAddress &peerAddr() const;
//本weosocket的连接状态
bool connected() const;
bool disconnected() const;
//关闭本websocket
void shutdown();//close write
void forceClose();//close
//设置和获取本websocket的上下文,由用户存入一些业务数据,
//any类型意味着可以存取任意类型的对象。
void setContext(const any &context);
any *getMutableContext();