mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
add WebSocketServlet by "fuwangqin" <niukey@qq.com>
This commit is contained in:
parent
e5c39cb5c8
commit
0707afa35f
@ -1,6 +1,9 @@
|
||||
修改历史列表:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
479) 2017.5.31
|
||||
479.1) featur: add WebSocketServlet by "fuwangqin" <niukey@qq.com>
|
||||
|
||||
478) 2017.5.27
|
||||
478.1) bugfix: websocket::make_frame_header 中当 payload_len 为 126 时会遇到
|
||||
内存跨界问题 --- found by "lindawei" <672496008@qq.com>
|
||||
|
@ -100,7 +100,7 @@ public:
|
||||
* @return {bool} 返回处理结果,返回 false 表示处理失败或处理成功且不保持
|
||||
* 长连接,应关闭连接
|
||||
*/
|
||||
bool doRun();
|
||||
bool doRun(void);
|
||||
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数
|
||||
|
@ -1,156 +1,165 @@
|
||||
#pragma once
|
||||
#include "stdlib/acl_mymalloc.h"
|
||||
#include "HttpServlet.hpp"
|
||||
#include "websocket.hpp"
|
||||
#include "acl_cpp/acl_cpp_define.hpp"
|
||||
#include "acl_cpp/http/HttpServlet.hpp"
|
||||
|
||||
namespace acl
|
||||
{
|
||||
class WebSocketServlet: public HttpServlet
|
||||
|
||||
class websocket;
|
||||
class session;
|
||||
|
||||
class WebSocketServlet: public HttpServlet
|
||||
{
|
||||
public:
|
||||
WebSocketServlet(void);
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param stream {socket_stream*} 当在 acl_master 服务器框架控制下
|
||||
* 运行时,该参数必须非空;当在 apache 下以 CGI 方式运行时,该参数
|
||||
* 设为 NULL;另外,该函数内部不会关闭流连接,应用应自行处理流对象
|
||||
* 的关闭情况,这样可以方便与 acl_master 架构结合
|
||||
* @param session {session*} 每一个 HttpServlet 对象一个 session 对象
|
||||
*/
|
||||
WebSocketServlet(socket_stream* stream, session* session);
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param stream {socket_stream*} 当在 acl_master 服务器框架控制下
|
||||
* 运行时,该参数必须非空;当在 apache 下以 CGI 方式运行时,该参数
|
||||
* 设为 NULL;另外,该函数内部不会关闭流连接,应用应自行处理流对象
|
||||
* 的关闭情况,这样可以方便与 acl_master 架构结合
|
||||
* @param memcache_addr {const char*}
|
||||
*/
|
||||
WebSocketServlet(socket_stream* stream,
|
||||
const char* memcache_addr = "127.0.0.1:11211");
|
||||
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数,
|
||||
* 该函数首先会调用 start 过程,然后根据 start 的返回结果及请求/响应
|
||||
* 对象是否要求保持长连接来决定是否需要与客户端保持长连接.
|
||||
* @return {bool} 返回处理结果,返回 false 表示处理失败或处理成功且
|
||||
* 不保持长连接,应关闭连接
|
||||
*/
|
||||
|
||||
virtual ~WebSocketServlet(void);
|
||||
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数
|
||||
* @param session {session&} 存储 session 数据的对象
|
||||
* @param stream {socket_stream*} 当在 acl_master 服务器框架控制下
|
||||
* 运行时,该参数必须非空;当在 apache 下以 CGI 方式运行时,该参数
|
||||
* 设为 NULL;另外,该函数内部不会关闭流连接,应用应自行处理流对象
|
||||
* 的关闭情况,这样可以方便与 acl_master 架构结合
|
||||
* @return {bool} 返回处理结果
|
||||
*/
|
||||
virtual bool doRun(session& session, socket_stream* stream = NULL)
|
||||
{
|
||||
public:
|
||||
WebSocketServlet();
|
||||
/**
|
||||
* 构造函数
|
||||
* @param stream {socket_stream*} 当在 acl_master 服务器框架控制下
|
||||
* 运行时,该参数必须非空;当在 apache 下以 CGI 方式运行时,该参数
|
||||
* 设为 NULL;另外,该函数内部不会关闭流连接,应用应自行处理流对象
|
||||
* 的关闭情况,这样可以方便与 acl_master 架构结合
|
||||
* @param session {session*} 每一个 HttpServlet 对象一个 session 对象
|
||||
*/
|
||||
WebSocketServlet(socket_stream* stream, session* session);
|
||||
return HttpServlet::doRun(session, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param stream {socket_stream*} 当在 acl_master 服务器框架控制下
|
||||
* 运行时,该参数必须非空;当在 apache 下以 CGI 方式运行时,该参数
|
||||
* 设为 NULL;另外,该函数内部不会关闭流连接,应用应自行处理流对象
|
||||
* 的关闭情况,这样可以方便与 acl_master 架构结合
|
||||
* @param memcache_addr {const char*}
|
||||
*/
|
||||
WebSocketServlet(socket_stream* stream, const char* memcache_addr = "127.0.0.1:11211");
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数,
|
||||
* 调用本函数意味着采用 memcached 来存储 session 数据
|
||||
* @param memcached_addr {const char*} memcached 服务器地址,格式:IP:PORT
|
||||
* @param stream {socket_stream*} 含义同上
|
||||
* @return {bool} 返回处理结果
|
||||
*/
|
||||
virtual bool doRun(const char* memcached_addr, socket_stream* stream)
|
||||
{
|
||||
return HttpServlet::doRun(memcached_addr, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数,
|
||||
* 该函数首先会调用 start 过程,然后根据 start 的返回结果及请求/响应
|
||||
* 对象是否要求保持长连接来决定是否需要与客户端保持长连接.
|
||||
* @return {bool} 返回处理结果,返回 false 表示处理失败或处理成功且不保持
|
||||
* 长连接,应关闭连接
|
||||
*/
|
||||
virtual bool doRun(void);
|
||||
|
||||
virtual ~WebSocketServlet();
|
||||
/**
|
||||
* 发送二进制数据.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数
|
||||
* @param session {session&} 存储 session 数据的对象
|
||||
* @param stream {socket_stream*} 当在 acl_master 服务器框架控制下
|
||||
* 运行时,该参数必须非空;当在 apache 下以 CGI 方式运行时,该参数
|
||||
* 设为 NULL;另外,该函数内部不会关闭流连接,应用应自行处理流对象
|
||||
* 的关闭情况,这样可以方便与 acl_master 架构结合
|
||||
* @return {bool} 返回处理结果
|
||||
*/
|
||||
virtual bool doRun(session& session, socket_stream* stream = NULL)
|
||||
{
|
||||
return HttpServlet::doRun(session, stream);
|
||||
}
|
||||
bool send_binary(const char *buf, int len);
|
||||
|
||||
/**
|
||||
* HttpServlet 对象开始运行,接收 HTTP 请求,并回调以下 doXXX 虚函数,
|
||||
* 调用本函数意味着采用 memcached 来存储 session 数据
|
||||
* @param memcached_addr {const char*} memcached 服务器地址,格式:IP:PORT
|
||||
* @param stream {socket_stream*} 含义同上
|
||||
* @return {bool} 返回处理结果
|
||||
*/
|
||||
virtual bool doRun(const char* memcached_addr, socket_stream* stream)
|
||||
{
|
||||
return HttpServlet::doRun(memcached_addr, stream);
|
||||
}
|
||||
/**
|
||||
* 发送文本数据.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
|
||||
virtual bool doRun();
|
||||
/**
|
||||
* 发送二进制数据.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
bool send_text(const char *text);
|
||||
|
||||
bool send_binary(const char *buf, int len);
|
||||
/**
|
||||
* 发送pong 消息.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
bool send_pong(const char *buffer = NULL);
|
||||
|
||||
/**
|
||||
* 发送pong 消息.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
bool send_ping(const char *buffer = NULL);
|
||||
|
||||
/**
|
||||
* 发送文本数据.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
unsigned long long get_max_msg_len(void) const
|
||||
{
|
||||
return max_msg_len_;
|
||||
}
|
||||
|
||||
bool send_text(const char *text);
|
||||
/**
|
||||
* 设置最大消息长度,当websocket 消息大于这个值,将断开websocket连接.
|
||||
* @param unsigned long long{len} 新的长度
|
||||
*/
|
||||
void set_max_msg_len(unsigned long long len)
|
||||
{
|
||||
max_msg_len_ = len;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* websocket 关闭消息回调
|
||||
* @return {void}
|
||||
*/
|
||||
virtual void on_close(void);
|
||||
|
||||
/**
|
||||
* 发送pong 消息.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
bool send_pong(const char *buffer = NULL);
|
||||
/**
|
||||
* websocket ping 消息回调.
|
||||
* @param {const char *} buf 消息数据
|
||||
* @param {int} len 消息数据长度
|
||||
* @return {bool} false 断开连接。
|
||||
*/
|
||||
virtual bool on_ping(const char *buf, unsigned long long len) = 0;
|
||||
|
||||
/**
|
||||
* 发送pong 消息.
|
||||
* @param rw_timeout {const char *} 发送的数据
|
||||
* @return {bool} 错误 false.否则 true
|
||||
*/
|
||||
bool send_ping(const char *buffer = NULL);
|
||||
/**
|
||||
* websocket pong 消息回调.
|
||||
* @param {const char *} buf 消息数据
|
||||
* @param {int} len 消息数据长度
|
||||
* @return {bool} false 断开连接。
|
||||
*/
|
||||
virtual bool on_pong(const char *buf, unsigned long long len) = 0;
|
||||
|
||||
unsigned long long get_max_msg_len()
|
||||
{
|
||||
return max_msg_len_;
|
||||
}
|
||||
/**
|
||||
* websocket ping 消息回调.
|
||||
* @param data{char *} 回调数据缓存区。
|
||||
* @param len{unsigned long long}回调数据缓存区长度。
|
||||
* @param text{bool } true 为文本数据。否则是 二进制数据。
|
||||
* @return {bool} false 断开连接。
|
||||
*/
|
||||
virtual bool on_message(char *data, unsigned long long len, bool text) = 0;
|
||||
|
||||
/**
|
||||
* 设置最大消息长度,当websocket 消息大于这个值,将断开websocket连接.
|
||||
* @param unsigned long long{len} 新的长度
|
||||
*/
|
||||
void set_max_msg_len(unsigned long long len)
|
||||
{
|
||||
max_msg_len_ = len;
|
||||
}
|
||||
protected:
|
||||
private:
|
||||
// @override
|
||||
bool doWebsocket(HttpServletRequest&, HttpServletResponse&);
|
||||
|
||||
/**
|
||||
* websocket 关闭消息回调
|
||||
* @return {void}
|
||||
*/
|
||||
virtual void on_close();
|
||||
/**
|
||||
* websocket ping 消息回调.
|
||||
* @param {const char *} buf 消息数据
|
||||
* @param {int} len 消息数据长度
|
||||
* @return {bool} false 断开连接。
|
||||
*/
|
||||
virtual bool on_ping(const char *buf, unsigned long long len) = 0;
|
||||
/**
|
||||
* websocket pong 消息回调.
|
||||
* @param {const char *} buf 消息数据
|
||||
* @param {int} len 消息数据长度
|
||||
* @return {bool} false 断开连接。
|
||||
*/
|
||||
virtual bool on_pong(const char *buf, unsigned long long len) = 0;
|
||||
private:
|
||||
|
||||
/**
|
||||
* websocket ping 消息回调.
|
||||
* @param data{char *} 回调数据缓存区。
|
||||
* @param len{unsigned long long}回调数据缓存区长度。
|
||||
* @param text{bool } true 为文本数据。否则是 二进制数据。
|
||||
* @return {bool} false 断开连接。
|
||||
*/
|
||||
virtual bool on_message(char *data, unsigned long long len, bool text) = 0;
|
||||
unsigned long long max_msg_len_;
|
||||
websocket *ws_;
|
||||
|
||||
private:
|
||||
bool doWebsocket(HttpServletRequest&, HttpServletResponse&);
|
||||
private:
|
||||
char *recv_buffer_;
|
||||
int write_pos_;
|
||||
int opcode_;
|
||||
};
|
||||
|
||||
unsigned long long max_msg_len_;
|
||||
websocket *ws_;
|
||||
|
||||
char *recv_buffer_;
|
||||
int write_pos_;
|
||||
int opcode_;
|
||||
};
|
||||
}
|
||||
} // namespace acl
|
||||
|
@ -89,6 +89,7 @@
|
||||
#include "acl_cpp/http/http_request_pool.hpp"
|
||||
#include "acl_cpp/http/http_request_manager.hpp"
|
||||
#include "acl_cpp/http/websocket.hpp"
|
||||
#include "acl_cpp/http/WebSocketServlet.hpp"
|
||||
|
||||
#include "acl_cpp/db/query.hpp"
|
||||
#include "acl_cpp/db/mysql_conf.hpp"
|
||||
|
@ -672,6 +672,9 @@ copy $(TargetName).pdb ..\dist\lib\win32\$(TargetName).pdb /Y
|
||||
<File
|
||||
RelativePath=".\src\http\websocket.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\http\WebSocketServlet.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="hsocket"
|
||||
@ -1265,6 +1268,9 @@ copy $(TargetName).pdb ..\dist\lib\win32\$(TargetName).pdb /Y
|
||||
<File
|
||||
RelativePath=".\include\acl_cpp\http\websocket.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\acl_cpp\http\WebSocketServlet.hpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="hsocket"
|
||||
|
@ -585,6 +585,10 @@
|
||||
RelativePath=".\src\http\websocket.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\http\WebSocketServlet.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ipc"
|
||||
@ -1431,6 +1435,10 @@
|
||||
RelativePath=".\include\acl_cpp\http\websocket.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\acl_cpp\http\WebSocketServlet.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="ipc"
|
||||
|
@ -255,6 +255,7 @@ copy $(TargetName).pdb ..\dist\lib\win32\$(TargetName).pdb /Y
|
||||
<ClCompile Include="src\http\http_service.cpp" />
|
||||
<ClCompile Include="src\http\http_utils.cpp" />
|
||||
<ClCompile Include="src\http\websocket.cpp" />
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_client.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_server.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_service.cpp" />
|
||||
@ -434,6 +435,7 @@ copy $(TargetName).pdb ..\dist\lib\win32\$(TargetName).pdb /Y
|
||||
<ClInclude Include="include\acl_cpp\http\http_type.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\http_utils.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_client.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_server.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_service.hpp" />
|
||||
|
@ -286,6 +286,9 @@
|
||||
<ClCompile Include="src\http\websocket.cpp">
|
||||
<Filter>src\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp">
|
||||
<Filter>src\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\stdlib\sha1.cpp">
|
||||
<Filter>src\stdlib</Filter>
|
||||
</ClCompile>
|
||||
@ -651,6 +654,9 @@
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp">
|
||||
<Filter>include\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp">
|
||||
<Filter>include\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\HttpServlet.hpp">
|
||||
<Filter>include\http</Filter>
|
||||
</ClInclude>
|
||||
|
@ -449,6 +449,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
|
||||
<ClCompile Include="src\http\http_service.cpp" />
|
||||
<ClCompile Include="src\http\http_utils.cpp" />
|
||||
<ClCompile Include="src\http\websocket.cpp" />
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_client.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_server.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_service.cpp" />
|
||||
@ -628,6 +629,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
|
||||
<ClInclude Include="include\acl_cpp\http\http_type.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\http_utils.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_client.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_server.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_service.hpp" />
|
||||
|
@ -283,6 +283,9 @@
|
||||
<ClCompile Include="src\http\websocket.cpp">
|
||||
<Filter>Source Files\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp">
|
||||
<Filter>Source Files\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\stdlib\sha1.cpp">
|
||||
<Filter>Source Files\stdlib</Filter>
|
||||
</ClCompile>
|
||||
@ -648,6 +651,9 @@
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\HttpServlet.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
|
@ -449,6 +449,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
|
||||
<ClCompile Include="src\http\http_service.cpp" />
|
||||
<ClCompile Include="src\http\http_utils.cpp" />
|
||||
<ClCompile Include="src\http\websocket.cpp" />
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_client.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_server.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_service.cpp" />
|
||||
@ -628,6 +629,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
|
||||
<ClInclude Include="include\acl_cpp\http\http_type.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\http_utils.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_client.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_server.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_service.hpp" />
|
||||
|
@ -283,6 +283,9 @@
|
||||
<ClCompile Include="src\http\websocket.cpp">
|
||||
<Filter>Source Files\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp">
|
||||
<Filter>Source Files\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\stdlib\sha1.cpp">
|
||||
<Filter>Source Files\stdlib</Filter>
|
||||
</ClCompile>
|
||||
@ -648,6 +651,9 @@
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\HttpServlet.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
|
@ -449,6 +449,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
|
||||
<ClCompile Include="src\http\http_service.cpp" />
|
||||
<ClCompile Include="src\http\http_utils.cpp" />
|
||||
<ClCompile Include="src\http\websocket.cpp" />
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_client.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_server.cpp" />
|
||||
<ClCompile Include="src\ipc\ipc_service.cpp" />
|
||||
@ -628,6 +629,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
|
||||
<ClInclude Include="include\acl_cpp\http\http_type.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\http_utils.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_client.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_server.hpp" />
|
||||
<ClInclude Include="include\acl_cpp\ipc\ipc_service.hpp" />
|
||||
|
@ -283,6 +283,9 @@
|
||||
<ClCompile Include="src\http\websocket.cpp">
|
||||
<Filter>Source Files\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\http\WebSocketServlet.cpp">
|
||||
<Filter>Source Files\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\stdlib\sha1.cpp">
|
||||
<Filter>Source Files\stdlib</Filter>
|
||||
</ClCompile>
|
||||
@ -648,6 +651,9 @@
|
||||
<ClInclude Include="include\acl_cpp\http\websocket.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\WebSocketServlet.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\acl_cpp\http\HttpServlet.hpp">
|
||||
<Filter>Header Files\http</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1,181 +1,191 @@
|
||||
/**
|
||||
* Copyright (C) 2015-2018
|
||||
* All rights reserved.
|
||||
*
|
||||
* AUTHOR(S)
|
||||
* Fu wangqin
|
||||
* E-mail: "fuwangqin" <niukey@qq.com>
|
||||
*
|
||||
* VERSION
|
||||
* Wed 31 May 2017 02:37:14 PM CST
|
||||
*/
|
||||
|
||||
#include "acl_stdafx.hpp"
|
||||
#ifndef ACL_PREPARE_COMPILE
|
||||
#include "acl_cpp/stdlib/log.hpp"
|
||||
#include "acl_cpp/stream/socket_stream.hpp"
|
||||
#include "acl_cpp/session/session.hpp"
|
||||
#include "acl_cpp/http/websocket.hpp"
|
||||
#include "acl_cpp/http/WebSocketServlet.hpp"
|
||||
#endif
|
||||
|
||||
namespace acl
|
||||
{
|
||||
WebSocketServlet::WebSocketServlet(socket_stream* stream, session* session)
|
||||
:HttpServlet(stream, session),
|
||||
max_msg_len_(100 * 1024*1024),
|
||||
ws_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketServlet::WebSocketServlet(
|
||||
socket_stream* stream,
|
||||
const char* memcache_addr )
|
||||
:HttpServlet(stream, memcache_addr),
|
||||
max_msg_len_(100 * 1024 * 1024),
|
||||
ws_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketServlet::WebSocketServlet()
|
||||
:max_msg_len_(100 * 1024 * 1024),
|
||||
ws_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketServlet::~WebSocketServlet()
|
||||
|
||||
WebSocketServlet::WebSocketServlet(socket_stream* stream, session* session)
|
||||
: HttpServlet(stream, session)
|
||||
, max_msg_len_(100 * 1024*1024)
|
||||
, ws_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketServlet::WebSocketServlet(socket_stream* stream,
|
||||
const char* memcache_addr)
|
||||
:HttpServlet(stream, memcache_addr)
|
||||
, max_msg_len_(100 * 1024 * 1024)
|
||||
, ws_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketServlet::WebSocketServlet(void)
|
||||
:max_msg_len_(100 * 1024 * 1024),
|
||||
ws_(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebSocketServlet::~WebSocketServlet(void)
|
||||
{
|
||||
if (ws_)
|
||||
delete ws_;
|
||||
ws_ = NULL;
|
||||
}
|
||||
|
||||
bool WebSocketServlet::doRun(void)
|
||||
{
|
||||
if (!ws_)
|
||||
{
|
||||
bool ret = HttpServlet::doRun();
|
||||
//websocket upgrade ok.
|
||||
//maybe http without keepalive ,
|
||||
//return false,framework will close this connection.
|
||||
if (ws_)
|
||||
delete ws_;
|
||||
ws_ = NULL;
|
||||
}
|
||||
|
||||
bool WebSocketServlet::doRun()
|
||||
{
|
||||
if (!ws_)
|
||||
{
|
||||
bool ret = HttpServlet::doRun();
|
||||
//websocket upgrade ok.
|
||||
//maybe http without keepalive ,
|
||||
//return false,framework will close this connection.
|
||||
if (ws_)
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ws_->read_frame_head() == false)
|
||||
return false;
|
||||
|
||||
unsigned long long len = ws_->get_frame_payload_len();
|
||||
if (len > max_msg_len_)
|
||||
{
|
||||
logger_error("payload too large error: %llu", len);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
if (!recv_buffer_)
|
||||
{
|
||||
recv_buffer_ = (char*)acl_mymalloc((size_t)len + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//frame not finish.
|
||||
recv_buffer_ = (char*)acl_myrealloc(recv_buffer_, write_pos_ + (size_t)len + 1);
|
||||
}
|
||||
|
||||
if (ws_->read_frame_data(recv_buffer_+ write_pos_, len) < 0)
|
||||
{
|
||||
write_pos_ = 0;
|
||||
acl_myfree(recv_buffer_);
|
||||
recv_buffer_ = NULL;
|
||||
return false;
|
||||
}
|
||||
write_pos_ += len;
|
||||
recv_buffer_[write_pos_] = '\0';
|
||||
}
|
||||
int opcode = ws_->get_frame_opcode();
|
||||
bool ret = false;
|
||||
|
||||
if (ws_->get_frame_fin() == false)
|
||||
{
|
||||
//safe opcode.
|
||||
if(opcode != FRAME_CONTINUATION)
|
||||
opcode_ = opcode;
|
||||
return true;
|
||||
}
|
||||
|
||||
//frame is finish callback frame.
|
||||
if (opcode == FRAME_CONTINUATION)
|
||||
{
|
||||
opcode = opcode_;
|
||||
}
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case FRAME_PING:
|
||||
ret = on_ping(recv_buffer_, write_pos_);
|
||||
break;
|
||||
case FRAME_PONG:
|
||||
ret = on_pong(recv_buffer_, write_pos_);
|
||||
break;
|
||||
case FRAME_CLOSE:
|
||||
on_close();
|
||||
break;
|
||||
case FRAME_TEXT:
|
||||
case FRAME_BINARY:
|
||||
{
|
||||
ret = on_message(recv_buffer_, write_pos_,
|
||||
ws_->get_frame_opcode() == FRAME_TEXT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logger_error("unknown websocket Frame opcode error: %d",
|
||||
ws_->get_frame_opcode());
|
||||
}
|
||||
if (recv_buffer_)
|
||||
{
|
||||
acl_myfree(recv_buffer_);
|
||||
recv_buffer_ = NULL;
|
||||
write_pos_ = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ws_->read_frame_head() == false)
|
||||
return false;
|
||||
|
||||
bool WebSocketServlet::send_binary(const char *recv_buffer_, int len)
|
||||
unsigned long long len = ws_->get_frame_payload_len();
|
||||
if (len > max_msg_len_)
|
||||
{
|
||||
ws_->set_frame_opcode(FRAME_BINARY);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(len);
|
||||
return ws_->send_frame_data(recv_buffer_, len);
|
||||
logger_error("payload too large error: %llu", len);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebSocketServlet::send_text(const char *recv_buffer_fer)
|
||||
if (len > 0)
|
||||
{
|
||||
ws_->set_frame_opcode(FRAME_TEXT);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(strlen(recv_buffer_fer));
|
||||
return ws_->send_frame_data(recv_buffer_fer, strlen(recv_buffer_fer));
|
||||
if (!recv_buffer_)
|
||||
recv_buffer_ = (char*) acl_mymalloc((size_t)len + 1);
|
||||
else
|
||||
//frame not finish.
|
||||
recv_buffer_ = (char*) acl_myrealloc(recv_buffer_,
|
||||
write_pos_ + (size_t)len + 1);
|
||||
|
||||
if (ws_->read_frame_data(recv_buffer_+ write_pos_, len) < 0)
|
||||
{
|
||||
write_pos_ = 0;
|
||||
acl_myfree(recv_buffer_);
|
||||
recv_buffer_ = NULL;
|
||||
return false;
|
||||
}
|
||||
write_pos_ += len;
|
||||
recv_buffer_[write_pos_] = '\0';
|
||||
}
|
||||
|
||||
bool WebSocketServlet::send_pong(const char *text)
|
||||
{
|
||||
size_t len = !text ? 0 : strlen(text);
|
||||
ws_->set_frame_opcode(FRAME_PONG);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(len);
|
||||
return ws_->send_frame_data(text, len);
|
||||
}
|
||||
int opcode = ws_->get_frame_opcode();
|
||||
bool ret = false;
|
||||
|
||||
bool WebSocketServlet::send_ping(const char *text)
|
||||
if (ws_->get_frame_fin() == false)
|
||||
{
|
||||
size_t len = !text ? 0 : strlen(text);
|
||||
ws_->set_frame_opcode(FRAME_PING);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(len);
|
||||
return ws_->send_frame_data(text, len);
|
||||
}
|
||||
|
||||
bool WebSocketServlet::doWebsocket(HttpServletRequest&, HttpServletResponse&)
|
||||
{
|
||||
acl_assert(!ws_);
|
||||
ws_ = new websocket(*getStream());
|
||||
//safe opcode.
|
||||
if(opcode != FRAME_CONTINUATION)
|
||||
opcode_ = opcode;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebSocketServlet::on_close()
|
||||
//frame is finish callback frame.
|
||||
if (opcode == FRAME_CONTINUATION)
|
||||
opcode = opcode_;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case FRAME_PING:
|
||||
ret = on_ping(recv_buffer_, write_pos_);
|
||||
break;
|
||||
case FRAME_PONG:
|
||||
ret = on_pong(recv_buffer_, write_pos_);
|
||||
break;
|
||||
case FRAME_CLOSE:
|
||||
on_close();
|
||||
break;
|
||||
case FRAME_TEXT:
|
||||
case FRAME_BINARY:
|
||||
ret = on_message(recv_buffer_, write_pos_,
|
||||
ws_->get_frame_opcode() == FRAME_TEXT);
|
||||
break;
|
||||
default:
|
||||
logger_error("unknown websocket Frame opcode error: %d",
|
||||
ws_->get_frame_opcode());
|
||||
break;
|
||||
}
|
||||
|
||||
if (recv_buffer_)
|
||||
{
|
||||
acl_myfree(recv_buffer_);
|
||||
recv_buffer_ = NULL;
|
||||
write_pos_ = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WebSocketServlet::send_binary(const char *buffer, int len)
|
||||
{
|
||||
ws_->set_frame_opcode(FRAME_BINARY);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(len);
|
||||
return ws_->send_frame_data(buffer, len);
|
||||
}
|
||||
|
||||
bool WebSocketServlet::send_text(const char *buffer)
|
||||
{
|
||||
ws_->set_frame_opcode(FRAME_TEXT);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(strlen(buffer));
|
||||
return ws_->send_frame_data(buffer, strlen(buffer));
|
||||
}
|
||||
|
||||
bool WebSocketServlet::send_pong(const char *text)
|
||||
{
|
||||
size_t len = !text ? 0 : strlen(text);
|
||||
ws_->set_frame_opcode(FRAME_PONG);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(len);
|
||||
return ws_->send_frame_data(text, len);
|
||||
}
|
||||
|
||||
bool WebSocketServlet::send_ping(const char *text)
|
||||
{
|
||||
size_t len = !text ? 0 : strlen(text);
|
||||
ws_->set_frame_opcode(FRAME_PING);
|
||||
ws_->set_frame_fin(true);
|
||||
ws_->set_frame_payload_len(len);
|
||||
return ws_->send_frame_data(text, len);
|
||||
}
|
||||
|
||||
bool WebSocketServlet::doWebsocket(HttpServletRequest&, HttpServletResponse&)
|
||||
{
|
||||
acl_assert(!ws_);
|
||||
ws_ = new websocket(*getStream());
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebSocketServlet::on_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace acl
|
||||
|
Loading…
Reference in New Issue
Block a user