Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
11a7d1e6
Commit
11a7d1e6
authored
Dec 26, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成tcp服务器/客户端 c api
parent
56397628
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
658 行增加
和
329 行删除
+658
-329
api/include/events_objects.h
+1
-18
api/include/mediakit.h
+1
-1
api/include/tcp.h
+226
-0
api/include/websocket.h
+0
-105
api/source/common.cpp
+2
-2
api/source/events_objects.cpp
+0
-54
api/source/tcp.cpp
+299
-0
api/source/websocket.cpp
+0
-110
api/tests/websocket.c
+121
-35
src/Http/WebSocketClient.h
+8
-4
没有找到文件。
api/include/events_objects.h
查看文件 @
11a7d1e6
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#ifndef MK_EVENT_OBJECTS_H
#ifndef MK_EVENT_OBJECTS_H
#define MK_EVENT_OBJECTS_H
#define MK_EVENT_OBJECTS_H
#include "common.h"
#include "common.h"
#include "tcp.h"
#ifdef __cplusplus
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
#endif
#endif
...
@@ -123,24 +124,6 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema,
...
@@ -123,24 +124,6 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema,
//MediaSource::for_each_media()
//MediaSource::for_each_media()
API_EXPORT
void
API_CALL
mk_media_source_for_each
(
void
*
user_data
,
on_mk_media_source_find_cb
cb
);
API_EXPORT
void
API_CALL
mk_media_source_for_each
(
void
*
user_data
,
on_mk_media_source_find_cb
cb
);
///////////////////////////////////////////TcpSession/////////////////////////////////////////////
//TcpSession对象的C映射
typedef
void
*
mk_tcp_session
;
//TcpSession::safeShutdown()
API_EXPORT
void
API_CALL
mk_tcp_session_shutdown
(
const
mk_tcp_session
ctx
,
int
err
,
const
char
*
err_msg
);
//TcpSession::get_peer_ip()
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_peer_ip
(
const
mk_tcp_session
ctx
);
//TcpSession::get_local_ip()
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_local_ip
(
const
mk_tcp_session
ctx
);
//TcpSession::get_peer_port()
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_peer_port
(
const
mk_tcp_session
ctx
);
//TcpSession::get_local_port()
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_local_port
(
const
mk_tcp_session
ctx
);
//TcpSession::send()
API_EXPORT
void
API_CALL
mk_tcp_session_send
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
);
//切换到该对象所在线程后再TcpSession::send()
API_EXPORT
void
API_CALL
mk_tcp_session_send_safe
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
);
///////////////////////////////////////////HttpBody/////////////////////////////////////////////
///////////////////////////////////////////HttpBody/////////////////////////////////////////////
//HttpBody对象的C映射
//HttpBody对象的C映射
typedef
void
*
mk_http_body
;
typedef
void
*
mk_http_body
;
...
...
api/include/mediakit.h
查看文件 @
11a7d1e6
...
@@ -35,6 +35,6 @@
...
@@ -35,6 +35,6 @@
#include "player.h"
#include "player.h"
#include "pusher.h"
#include "pusher.h"
#include "events.h"
#include "events.h"
#include "
websocket
.h"
#include "
tcp
.h"
#endif
/* MK_API_H_ */
#endif
/* MK_API_H_ */
api/include/tcp.h
0 → 100644
查看文件 @
11a7d1e6
/*
* MIT License
*
* Copyright (c) 2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MK_TCP_H
#define MK_TCP_H
#include "common.h"
#ifdef __cplusplus
extern
"C"
{
#endif
///////////////////////////////////////////TcpSession/////////////////////////////////////////////
//TcpSession对象的C映射
typedef
void
*
mk_tcp_session
;
//TcpSession::safeShutdown()
API_EXPORT
void
API_CALL
mk_tcp_session_shutdown
(
const
mk_tcp_session
ctx
,
int
err
,
const
char
*
err_msg
);
//TcpSession::get_peer_ip()
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_peer_ip
(
const
mk_tcp_session
ctx
);
//TcpSession::get_local_ip()
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_local_ip
(
const
mk_tcp_session
ctx
);
//TcpSession::get_peer_port()
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_peer_port
(
const
mk_tcp_session
ctx
);
//TcpSession::get_local_port()
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_local_port
(
const
mk_tcp_session
ctx
);
//TcpSession::send()
API_EXPORT
void
API_CALL
mk_tcp_session_send
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
);
//切换到该对象所在线程后再TcpSession::send()
API_EXPORT
void
API_CALL
mk_tcp_session_send_safe
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
);
///////////////////////////////////////////自定义tcp服务/////////////////////////////////////////////
typedef
struct
{
/**
* 收到mk_tcp_session创建对象
* @param server_port 服务器端口号
* @param session 会话处理对象
*/
void
(
API_CALL
*
on_mk_tcp_session_create
)(
uint16_t
server_port
,
mk_tcp_session
session
);
/**
* 收到客户端发过来的数据
* @param server_port 服务器端口号
* @param session 会话处理对象
* @param data 数据指针
* @param len 数据长度
*/
void
(
API_CALL
*
on_mk_tcp_session_data
)(
uint16_t
server_port
,
mk_tcp_session
session
,
const
char
*
data
,
int
len
);
/**
* 每隔2秒的定时器,用于管理超时等任务
* @param server_port 服务器端口号
* @param session 会话处理对象
*/
void
(
API_CALL
*
on_mk_tcp_session_manager
)(
uint16_t
server_port
,
mk_tcp_session
session
);
/**
* 一般由于客户端断开tcp触发
* @param server_port 服务器端口号
* @param session 会话处理对象
* @param code 错误代码
* @param msg 错误提示
*/
void
(
API_CALL
*
on_mk_tcp_session_disconnect
)(
uint16_t
server_port
,
mk_tcp_session
session
,
int
code
,
const
char
*
msg
);
}
mk_tcp_session_events
;
typedef
enum
{
//普通的tcp
mk_type_tcp
=
0
,
//ssl类型的tcp
mk_type_ssl
=
1
,
//基于websocket的连接
mk_type_ws
=
2
,
//基于ssl websocket的连接
mk_type_wss
=
3
}
mk_tcp_type
;
/**
* tcp会话对象附着用户数据
* 该函数只对mk_tcp_server_server_start启动的服务类型有效
* @param session 会话对象
* @param user_data 用户数据指针
*/
API_EXPORT
void
API_CALL
mk_tcp_session_set_user_data
(
mk_tcp_session
session
,
void
*
user_data
);
/**
* 获取tcp会话对象上附着的用户数据
* 该函数只对mk_tcp_server_server_start启动的服务类型有效
* @param session tcp会话对象
* @return 用户数据指针
*/
API_EXPORT
void
*
API_CALL
mk_tcp_session_get_user_data
(
mk_tcp_session
session
);
/**
* 开启tcp服务器
* @param port 监听端口号,0则为随机
* @param type 服务器类型
*/
API_EXPORT
uint16_t
API_CALL
mk_tcp_server_server_start
(
uint16_t
port
,
mk_tcp_type
type
);
/**
* 监听tcp服务器事件
*/
API_EXPORT
void
API_CALL
mk_tcp_server_events_listen
(
const
mk_tcp_session_events
*
events
);
///////////////////////////////////////////自定义tcp客户端/////////////////////////////////////////////
typedef
void
*
mk_tcp_client
;
typedef
struct
{
/**
* tcp客户端连接服务器成功或失败回调
* @param client tcp客户端
* @param code 0为连接成功,否则为失败原因
* @param msg 连接失败错误提示
*/
void
(
API_CALL
*
on_mk_tcp_client_connect
)(
mk_tcp_client
client
,
int
code
,
const
char
*
msg
);
/**
* tcp客户端与tcp服务器之间断开回调
* 一般是eof事件导致
* @param client tcp客户端
* @param code 错误代码
* @param msg 错误提示
*/
void
(
API_CALL
*
on_mk_tcp_client_disconnect
)(
mk_tcp_client
client
,
int
code
,
const
char
*
msg
);
/**
* 收到tcp服务器发来的数据
* @param client tcp客户端
* @param data 数据指针
* @param len 数据长度
*/
void
(
API_CALL
*
on_mk_tcp_client_data
)(
mk_tcp_client
client
,
const
char
*
data
,
int
len
);
/**
* 每隔2秒的定时器,用于管理超时等任务
* @param client tcp客户端
*/
void
(
API_CALL
*
on_mk_tcp_client_manager
)(
mk_tcp_client
client
);
}
mk_tcp_client_events
;
/**
* 创建tcp客户端
* @param events 回调函数结构体
* @param user_data 用户数据指针
* @param type 客户端类型
* @return 客户端对象
*/
API_EXPORT
mk_tcp_client
API_CALL
mk_tcp_client_create
(
mk_tcp_client_events
*
events
,
mk_tcp_type
type
);
/**
* 释放tcp客户端
* @param ctx 客户端对象
*/
API_EXPORT
void
API_CALL
mk_tcp_client_release
(
mk_tcp_client
ctx
);
/**
* 发起连接
* @param ctx 客户端对象
* @param host 服务器ip或域名
* @param port 服务器端口号
* @param time_out_sec 超时时间
*/
API_EXPORT
void
API_CALL
mk_tcp_client_connect
(
mk_tcp_client
ctx
,
const
char
*
host
,
uint16_t
port
,
float
time_out_sec
);
/**
* 非线程安全的发送数据
* 开发者如果能确保在本对象网络线程内,可以调用此此函数
* @param ctx 客户端对象
* @param data 数据指针
* @param len 数据长度,等于0时,内部通过strlen获取
*/
API_EXPORT
void
API_CALL
mk_tcp_client_send
(
mk_tcp_client
ctx
,
const
char
*
data
,
int
len
);
/**
* 切换到本对象的网络线程后再发送数据
* @param ctx 客户端对象
* @param data 数据指针
* @param len 数据长度,等于0时,内部通过strlen获取
*/
API_EXPORT
void
API_CALL
mk_tcp_client_send_safe
(
mk_tcp_client
ctx
,
const
char
*
data
,
int
len
);
/**
* 客户端附着用户数据
* @param ctx 客户端对象
* @param user_data 用户数据指针
*/
API_EXPORT
void
API_CALL
mk_tcp_client_set_user_data
(
mk_tcp_client
ctx
,
void
*
user_data
);
/**
* 获取客户端对象上附着的用户数据
* @param ctx 客户端对象
* @return 用户数据指针
*/
API_EXPORT
void
*
API_CALL
mk_tcp_client_get_user_data
(
mk_tcp_client
ctx
);
#ifdef __cplusplus
}
#endif
#endif //MK_TCP_H
api/include/websocket.h
deleted
100644 → 0
查看文件 @
56397628
/*
* MIT License
*
* Copyright (c) 2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MK_WEBSOCKET_H
#define MK_WEBSOCKET_H
#include "common.h"
#include "events_objects.h"
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
{
/**
* 当websocket客户端连接服务器时触发
* @param session 会话处理对象
*/
void
(
API_CALL
*
on_mk_websocket_session_create
)(
mk_tcp_session
session
);
/**
* session会话对象销毁时触发
* 请在本回调中清理释放你的用户数据
* 本事件中不能调用mk_tcp_session_send/mk_tcp_session_send_safe函数
* @param session 会话处理对象
*/
void
(
API_CALL
*
on_mk_websocket_session_destory
)(
mk_tcp_session
session
);
/**
* 收到websocket客户端发过来的数据
* @param session 会话处理对象
* @param data 数据指针
* @param len 数据长度
*/
void
(
API_CALL
*
on_mk_websocket_session_data
)(
mk_tcp_session
session
,
const
char
*
data
,
int
len
);
/**
* 每隔2秒的定时器,用于管理超时等任务
* @param session 会话处理对象
*/
void
(
API_CALL
*
on_mk_websocket_session_manager
)(
mk_tcp_session
session
);
/**
* on_mk_websocket_session_destory之前触发on_mk_websocket_session_err
* 一般由于客户端断开tcp触发
* 本事件中可以调用mk_tcp_session_send_safe函数
* @param session 会话处理对象
* @param code 错误代码
* @param msg 错误提示
*/
void
(
API_CALL
*
on_mk_websocket_session_err
)(
mk_tcp_session
session
,
int
code
,
const
char
*
msg
);
}
mk_websocket_events
;
API_EXPORT
void
API_CALL
mk_websocket_events_listen
(
const
mk_websocket_events
*
events
);
/**
* 往websocket会话对象附着用户数据
* @param session websocket会话对象
* @param user_data 用户数据指针
*/
API_EXPORT
void
API_CALL
mk_websocket_session_set_user_data
(
mk_tcp_session
session
,
void
*
user_data
);
/**
* 获取websocket会话对象上附着的用户数据
* @param session websocket会话对象
* @return 用户数据指针
*/
API_EXPORT
void
*
API_CALL
mk_websocket_session_get_user_data
(
mk_tcp_session
session
);
/**
* 开启websocket服务器,需要指出的是,websocket服务器包含了Http服务器的所有功能
* 调用mk_websocket_server_start后不用再调用mk_http_server_start
* @param port 端口号,0则随机
* @param ssl 是否为wss/ws
* @return 端口号,0代表失败
*/
API_EXPORT
uint16_t
API_CALL
mk_websocket_server_start
(
uint16_t
port
,
int
ssl
);
#ifdef __cplusplus
}
#endif
#endif //MK_WEBSOCKET_H
api/source/common.cpp
查看文件 @
11a7d1e6
...
@@ -64,7 +64,7 @@ API_EXPORT void API_CALL mk_env_init(const mk_config *cfg) {
...
@@ -64,7 +64,7 @@ API_EXPORT void API_CALL mk_env_init(const mk_config *cfg) {
cfg
->
ssl_pwd
);
cfg
->
ssl_pwd
);
}
}
extern
void
mk_websocket_server_stop
();
extern
void
stopAllTcpServer
();
API_EXPORT
void
API_CALL
mk_stop_all_server
(){
API_EXPORT
void
API_CALL
mk_stop_all_server
(){
CLEAR_ARR
(
rtsp_server
);
CLEAR_ARR
(
rtsp_server
);
...
@@ -72,7 +72,7 @@ API_EXPORT void API_CALL mk_stop_all_server(){
...
@@ -72,7 +72,7 @@ API_EXPORT void API_CALL mk_stop_all_server(){
CLEAR_ARR
(
http_server
);
CLEAR_ARR
(
http_server
);
udpRtpServer
=
nullptr
;
udpRtpServer
=
nullptr
;
tcpRtpServer
=
nullptr
;
tcpRtpServer
=
nullptr
;
mk_websocket_server_stop
();
stopAllTcpServer
();
}
}
API_EXPORT
void
API_CALL
mk_env_init1
(
int
thread_num
,
API_EXPORT
void
API_CALL
mk_env_init1
(
int
thread_num
,
...
...
api/source/events_objects.cpp
查看文件 @
11a7d1e6
...
@@ -228,60 +228,6 @@ API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_s
...
@@ -228,60 +228,6 @@ API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_s
});
});
}
}
///////////////////////////////////////////TcpSession/////////////////////////////////////////////
API_EXPORT
void
API_CALL
mk_tcp_session_shutdown
(
const
mk_tcp_session
ctx
,
int
err
,
const
char
*
err_msg
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
session
->
safeShutdown
(
SockException
((
ErrCode
)
err
,
err_msg
));
}
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_peer_ip
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_peer_ip
().
c_str
();
}
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_local_ip
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_local_ip
().
c_str
();
}
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_peer_port
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_peer_port
();
}
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_local_port
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_local_port
();
}
API_EXPORT
void
API_CALL
mk_tcp_session_send
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
){
assert
(
ctx
&&
data
);
if
(
!
len
){
len
=
strlen
(
data
);
}
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
session
->
send
(
data
,
len
);
}
API_EXPORT
void
API_CALL
mk_tcp_session_send_safe
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
){
assert
(
ctx
&&
data
);
if
(
!
len
){
len
=
strlen
(
data
);
}
try
{
weak_ptr
<
TcpSession
>
weak_session
=
((
TcpSession
*
)
ctx
)
->
shared_from_this
();
string
str
=
string
(
data
,
len
);
((
TcpSession
*
)
ctx
)
->
async
([
weak_session
,
str
](){
auto
session_session
=
weak_session
.
lock
();
if
(
session_session
){
session_session
->
send
(
str
);
}
});
}
catch
(
std
::
exception
&
ex
){
WarnL
<<
"can not got the strong pionter of this mk_tcp_session:"
<<
ex
.
what
();
}
}
///////////////////////////////////////////HttpBody/////////////////////////////////////////////
///////////////////////////////////////////HttpBody/////////////////////////////////////////////
API_EXPORT
mk_http_body
API_CALL
mk_http_body_from_string
(
const
char
*
str
,
int
len
){
API_EXPORT
mk_http_body
API_CALL
mk_http_body_from_string
(
const
char
*
str
,
int
len
){
assert
(
str
);
assert
(
str
);
...
...
api/source/tcp.cpp
0 → 100644
查看文件 @
11a7d1e6
/*
* MIT License
*
* Copyright (c) 2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "tcp.h"
#include "Network/TcpSession.h"
#include "Network/TcpClient.h"
#include "Http/WebSocketClient.h"
#include "Http/WebSocketSession.h"
using
namespace
mediakit
;
////////////////////////////////////////////////////////////////////////////////////////
API_EXPORT
void
API_CALL
mk_tcp_session_shutdown
(
const
mk_tcp_session
ctx
,
int
err
,
const
char
*
err_msg
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
session
->
safeShutdown
(
SockException
((
ErrCode
)
err
,
err_msg
));
}
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_peer_ip
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_peer_ip
().
c_str
();
}
API_EXPORT
const
char
*
API_CALL
mk_tcp_session_local_ip
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_local_ip
().
c_str
();
}
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_peer_port
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_peer_port
();
}
API_EXPORT
uint16_t
API_CALL
mk_tcp_session_local_port
(
const
mk_tcp_session
ctx
){
assert
(
ctx
);
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
return
session
->
get_local_port
();
}
API_EXPORT
void
API_CALL
mk_tcp_session_send
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
){
assert
(
ctx
&&
data
);
if
(
!
len
){
len
=
strlen
(
data
);
}
TcpSession
*
session
=
(
TcpSession
*
)
ctx
;
session
->
send
(
data
,
len
);
}
API_EXPORT
void
API_CALL
mk_tcp_session_send_safe
(
const
mk_tcp_session
ctx
,
const
char
*
data
,
int
len
){
assert
(
ctx
&&
data
);
if
(
!
len
){
len
=
strlen
(
data
);
}
try
{
weak_ptr
<
TcpSession
>
weak_session
=
((
TcpSession
*
)
ctx
)
->
shared_from_this
();
string
str
=
string
(
data
,
len
);
((
TcpSession
*
)
ctx
)
->
async
([
weak_session
,
str
](){
auto
session_session
=
weak_session
.
lock
();
if
(
session_session
){
session_session
->
send
(
str
);
}
});
}
catch
(
std
::
exception
&
ex
){
WarnL
<<
"can not got the strong pionter of this mk_tcp_session:"
<<
ex
.
what
();
}
}
////////////////////////////////////////TcpSessionForC////////////////////////////////////////////////
static
TcpServer
::
Ptr
s_tcp_server
[
4
];
static
mk_tcp_session_events
s_events_server
=
{
0
};
class
TcpSessionForC
:
public
TcpSession
{
public
:
TcpSessionForC
(
const
Socket
::
Ptr
&
pSock
)
;
~
TcpSessionForC
()
override
=
default
;
void
onRecv
(
const
Buffer
::
Ptr
&
buffer
)
override
;
void
onError
(
const
SockException
&
err
)
override
;
void
onManager
()
override
;
void
*
_user_data
;
uint16_t
_local_port
;
};
TcpSessionForC
::
TcpSessionForC
(
const
Socket
::
Ptr
&
pSock
)
:
TcpSession
(
pSock
)
{
_local_port
=
get_local_port
();
if
(
s_events_server
.
on_mk_tcp_session_create
)
{
s_events_server
.
on_mk_tcp_session_create
(
_local_port
,
this
);
}
}
void
TcpSessionForC
::
onRecv
(
const
Buffer
::
Ptr
&
buffer
)
{
if
(
s_events_server
.
on_mk_tcp_session_data
)
{
s_events_server
.
on_mk_tcp_session_data
(
_local_port
,
this
,
buffer
->
data
(),
buffer
->
size
());
}
}
void
TcpSessionForC
::
onError
(
const
SockException
&
err
)
{
if
(
s_events_server
.
on_mk_tcp_session_disconnect
)
{
s_events_server
.
on_mk_tcp_session_disconnect
(
_local_port
,
this
,
err
.
getErrCode
(),
err
.
what
());
}
}
void
TcpSessionForC
::
onManager
()
{
if
(
s_events_server
.
on_mk_tcp_session_manager
)
{
s_events_server
.
on_mk_tcp_session_manager
(
_local_port
,
this
);
}
}
void
stopAllTcpServer
(){
CLEAR_ARR
(
s_tcp_server
);
}
API_EXPORT
void
API_CALL
mk_tcp_session_set_user_data
(
mk_tcp_session
session
,
void
*
user_data
){
assert
(
session
);
TcpSessionForC
*
obj
=
(
TcpSessionForC
*
)
session
;
obj
->
_user_data
=
user_data
;
}
API_EXPORT
void
*
API_CALL
mk_tcp_session_get_user_data
(
mk_tcp_session
session
){
assert
(
session
);
TcpSessionForC
*
obj
=
(
TcpSessionForC
*
)
session
;
return
obj
->
_user_data
;
}
API_EXPORT
void
API_CALL
mk_tcp_server_events_listen
(
const
mk_tcp_session_events
*
events
){
if
(
events
)
{
memcpy
(
&
s_events_server
,
events
,
sizeof
(
s_events_server
));
}
else
{
memset
(
&
s_events_server
,
0
,
sizeof
(
s_events_server
));
}
}
API_EXPORT
uint16_t
API_CALL
mk_tcp_server_server_start
(
uint16_t
port
,
mk_tcp_type
type
){
type
=
MAX
(
mk_type_tcp
,
MIN
(
type
,
mk_type_wss
));
try
{
s_tcp_server
[
type
]
=
std
::
make_shared
<
TcpServer
>
();
switch
(
type
)
{
case
mk_type_tcp
:
s_tcp_server
[
type
]
->
start
<
TcpSessionForC
>
(
port
);
break
;
case
mk_type_ssl
:
s_tcp_server
[
type
]
->
start
<
TcpSessionWithSSL
<
TcpSessionForC
>
>
(
port
);
break
;
case
mk_type_ws
:
s_tcp_server
[
type
]
->
start
<
WebSocketSession
<
TcpSessionForC
,
HttpSession
>>
(
port
);
break
;
case
mk_type_wss
:
s_tcp_server
[
type
]
->
start
<
WebSocketSession
<
TcpSessionForC
,
HttpsSession
>>
(
port
);
break
;
default
:
return
0
;
}
return
s_tcp_server
[
type
]
->
getPort
();
}
catch
(
std
::
exception
&
ex
)
{
s_tcp_server
[
type
].
reset
();
WarnL
<<
ex
.
what
();
return
0
;
}
}
///////////////////////////////////////////////////TcpClientForC/////////////////////////////////////////////////////////
class
TcpClientForC
:
public
TcpClient
{
public
:
typedef
std
::
shared_ptr
<
TcpClientForC
>
Ptr
;
TcpClientForC
(
mk_tcp_client_events
*
events
)
;
~
TcpClientForC
()
override
;
void
onRecv
(
const
Buffer
::
Ptr
&
pBuf
)
override
;
void
onErr
(
const
SockException
&
ex
)
override
;
void
onManager
()
override
;
void
onConnect
(
const
SockException
&
ex
)
override
;
void
setClient
(
mk_tcp_client
client
);
void
*
_user_data
;
private
:
mk_tcp_client_events
_events
;
mk_tcp_client
_client
;
};
TcpClientForC
::
TcpClientForC
(
mk_tcp_client_events
*
events
){
_events
=
*
events
;
}
void
TcpClientForC
::
onRecv
(
const
Buffer
::
Ptr
&
pBuf
)
{
if
(
_events
.
on_mk_tcp_client_data
){
_events
.
on_mk_tcp_client_data
(
_client
,
pBuf
->
data
(),
pBuf
->
size
());
}
}
void
TcpClientForC
::
onErr
(
const
SockException
&
ex
)
{
if
(
_events
.
on_mk_tcp_client_disconnect
){
_events
.
on_mk_tcp_client_disconnect
(
_client
,
ex
.
getErrCode
(),
ex
.
what
());
}
}
void
TcpClientForC
::
onManager
()
{
if
(
_events
.
on_mk_tcp_client_manager
){
_events
.
on_mk_tcp_client_manager
(
_client
);
}
}
void
TcpClientForC
::
onConnect
(
const
SockException
&
ex
)
{
if
(
_events
.
on_mk_tcp_client_connect
){
_events
.
on_mk_tcp_client_connect
(
_client
,
ex
.
getErrCode
(),
ex
.
what
());
}
}
TcpClientForC
::~
TcpClientForC
()
{
TraceL
<<
"mk_tcp_client_release:"
<<
_client
;
}
void
TcpClientForC
::
setClient
(
mk_tcp_client
client
)
{
_client
=
client
;
TraceL
<<
"mk_tcp_client_create:"
<<
_client
;
}
TcpClientForC
::
Ptr
*
mk_tcp_client_create_l
(
mk_tcp_client_events
*
events
,
mk_tcp_type
type
){
assert
(
events
);
type
=
MAX
(
mk_type_tcp
,
MIN
(
type
,
mk_type_wss
));
switch
(
type
)
{
case
mk_type_tcp
:
return
new
TcpClientForC
::
Ptr
(
new
TcpClientForC
(
events
));
case
mk_type_ssl
:
return
(
TcpClientForC
::
Ptr
*
)
new
shared_ptr
<
TcpSessionWithSSL
<
TcpClientForC
>
>
(
new
TcpSessionWithSSL
<
TcpClientForC
>
(
events
));
case
mk_type_ws
:
return
(
TcpClientForC
::
Ptr
*
)
new
shared_ptr
<
WebSocketClient
<
TcpClientForC
,
WebSocketHeader
::
TEXT
,
false
>
>
(
new
WebSocketClient
<
TcpClientForC
,
WebSocketHeader
::
TEXT
,
false
>
(
events
));
case
mk_type_wss
:
return
(
TcpClientForC
::
Ptr
*
)
new
shared_ptr
<
WebSocketClient
<
TcpClientForC
,
WebSocketHeader
::
TEXT
,
true
>
>
(
new
WebSocketClient
<
TcpClientForC
,
WebSocketHeader
::
TEXT
,
true
>
(
events
));
default
:
return
nullptr
;
}
}
API_EXPORT
mk_tcp_client
API_CALL
mk_tcp_client_create
(
mk_tcp_client_events
*
events
,
mk_tcp_type
type
){
auto
ret
=
mk_tcp_client_create_l
(
events
,
type
);
(
*
ret
)
->
setClient
(
ret
);
return
ret
;
}
API_EXPORT
void
API_CALL
mk_tcp_client_release
(
mk_tcp_client
ctx
){
assert
(
ctx
);
TcpClient
::
Ptr
*
client
=
(
TcpClient
::
Ptr
*
)
ctx
;
delete
client
;
}
API_EXPORT
void
API_CALL
mk_tcp_client_connect
(
mk_tcp_client
ctx
,
const
char
*
host
,
uint16_t
port
,
float
time_out_sec
){
assert
(
ctx
);
TcpClient
::
Ptr
*
client
=
(
TcpClient
::
Ptr
*
)
ctx
;
(
*
client
)
->
startConnect
(
host
,
port
);
}
API_EXPORT
void
API_CALL
mk_tcp_client_send
(
mk_tcp_client
ctx
,
const
char
*
data
,
int
len
){
assert
(
ctx
&&
data
);
TcpClient
::
Ptr
*
client
=
(
TcpClient
::
Ptr
*
)
ctx
;
(
*
client
)
->
send
(
data
,
len
);
}
API_EXPORT
void
API_CALL
mk_tcp_client_send_safe
(
mk_tcp_client
ctx
,
const
char
*
data
,
int
len
){
assert
(
ctx
&&
data
);
TcpClient
::
Ptr
*
client
=
(
TcpClient
::
Ptr
*
)
ctx
;
weak_ptr
<
TcpClient
>
weakClient
=
*
client
;
Buffer
::
Ptr
buf
=
(
*
client
)
->
obtainBuffer
(
data
,
len
);
(
*
client
)
->
async
([
weakClient
,
buf
](){
auto
strongClient
=
weakClient
.
lock
();
if
(
strongClient
){
strongClient
->
send
(
buf
);
}
});
}
API_EXPORT
void
API_CALL
mk_tcp_client_set_user_data
(
mk_tcp_client
ctx
,
void
*
user_data
){
assert
(
ctx
);
TcpClientForC
::
Ptr
*
client
=
(
TcpClientForC
::
Ptr
*
)
ctx
;
(
*
client
)
->
_user_data
=
user_data
;
}
API_EXPORT
void
*
API_CALL
mk_tcp_client_get_user_data
(
mk_tcp_client
ctx
){
assert
(
ctx
);
TcpClientForC
::
Ptr
*
client
=
(
TcpClientForC
::
Ptr
*
)
ctx
;
return
(
*
client
)
->
_user_data
;
}
api/source/websocket.cpp
deleted
100644 → 0
查看文件 @
56397628
/*
* MIT License
*
* Copyright (c) 2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "websocket.h"
#include "Http/HttpSession.h"
#include "Http/WebSocketSession.h"
using
namespace
mediakit
;
static
TcpServer
::
Ptr
websocket_server
[
2
];
static
mk_websocket_events
s_events
=
{
0
};
class
WebSocketSessionImp
:
public
TcpSession
{
public
:
WebSocketSessionImp
(
const
Socket
::
Ptr
&
pSock
)
:
TcpSession
(
pSock
){
if
(
s_events
.
on_mk_websocket_session_create
){
s_events
.
on_mk_websocket_session_create
(
this
);
}
}
virtual
~
WebSocketSessionImp
(){
if
(
s_events
.
on_mk_websocket_session_destory
){
s_events
.
on_mk_websocket_session_destory
(
this
);
}
}
void
onRecv
(
const
Buffer
::
Ptr
&
buffer
)
override
{
if
(
s_events
.
on_mk_websocket_session_data
){
s_events
.
on_mk_websocket_session_data
(
this
,
buffer
->
data
(),
buffer
->
size
());
}
}
void
onError
(
const
SockException
&
err
)
override
{
if
(
s_events
.
on_mk_websocket_session_err
){
s_events
.
on_mk_websocket_session_err
(
this
,
err
.
getErrCode
(),
err
.
what
());
}
}
void
onManager
()
override
{
if
(
s_events
.
on_mk_websocket_session_manager
){
s_events
.
on_mk_websocket_session_manager
(
this
);
}
}
void
*
_user_data
;
};
API_EXPORT
void
API_CALL
mk_websocket_events_listen
(
const
mk_websocket_events
*
events
){
if
(
events
){
memcpy
(
&
s_events
,
events
,
sizeof
(
s_events
));
}
else
{
memset
(
&
s_events
,
0
,
sizeof
(
s_events
));
}
}
API_EXPORT
void
API_CALL
mk_websocket_session_set_user_data
(
mk_tcp_session
session
,
void
*
user_data
){
assert
(
session
);
WebSocketSessionImp
*
obj
=
(
WebSocketSessionImp
*
)
session
;
obj
->
_user_data
=
user_data
;
}
API_EXPORT
void
*
API_CALL
mk_websocket_session_get_user_data
(
mk_tcp_session
session
){
assert
(
session
);
WebSocketSessionImp
*
obj
=
(
WebSocketSessionImp
*
)
session
;
return
obj
->
_user_data
;
}
API_EXPORT
uint16_t
API_CALL
mk_websocket_server_start
(
uint16_t
port
,
int
ssl
){
ssl
=
MAX
(
0
,
MIN
(
ssl
,
1
));
try
{
websocket_server
[
ssl
]
=
std
::
make_shared
<
TcpServer
>
();
if
(
ssl
){
websocket_server
[
ssl
]
->
start
<
WebSocketSession
<
WebSocketSessionImp
,
HttpsSession
>>
(
port
);
}
else
{
websocket_server
[
ssl
]
->
start
<
WebSocketSession
<
WebSocketSessionImp
,
HttpSession
>>
(
port
);
}
return
websocket_server
[
ssl
]
->
getPort
();
}
catch
(
std
::
exception
&
ex
)
{
websocket_server
[
ssl
].
reset
();
WarnL
<<
ex
.
what
();
return
0
;
}
}
void
mk_websocket_server_stop
(){
CLEAR_ARR
(
websocket_server
);
}
api/tests/websocket.c
查看文件 @
11a7d1e6
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <signal.h>
#include <signal.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include "mediakit.h"
#include "mediakit.h"
#ifdef _WIN32
#ifdef _WIN32
#include "windows.h"
#include "windows.h"
...
@@ -35,42 +36,37 @@
...
@@ -35,42 +36,37 @@
#endif
#endif
#define LOG_LEV 4
#define LOG_LEV 4
#define TCP_TYPE mk_type_wss
static
int
flag
=
1
;
static
void
s_on_exit
(
int
sig
){
flag
=
0
;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef
struct
{
typedef
struct
{
mk_tcp_session
_session
;
mk_tcp_session
_session
;
//下面你可以夹杂你的私货数据
//下面你可以夹杂你的私货数据
char
your_some_useful_data
[
1024
];
char
your_some_useful_data
[
1024
];
}
websocket
_user_data
;
}
tcp_session
_user_data
;
/**
/**
* 当
websocket
客户端连接服务器时触发
* 当
tcp
客户端连接服务器时触发
* @param session 会话处理对象
* @param session 会话处理对象
*/
*/
void
API_CALL
on_mk_
websocket_session_create
(
mk_tcp_session
session
){
void
API_CALL
on_mk_
tcp_session_create
(
uint16_t
server_port
,
mk_tcp_session
session
){
log_printf
(
LOG_LEV
,
"%s %d"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
));
log_printf
(
LOG_LEV
,
"%s %d"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
));
websocket_user_data
*
user_data
=
malloc
(
sizeof
(
websocket
_user_data
));
tcp_session_user_data
*
user_data
=
malloc
(
sizeof
(
tcp_session
_user_data
));
user_data
->
_session
=
session
;
user_data
->
_session
=
session
;
mk_websocket_session_set_user_data
(
session
,
user_data
);
mk_tcp_session_set_user_data
(
session
,
user_data
);
}
/**
* session会话对象销毁时触发
* 请在本回调中清理释放你的用户数据
* 本事件中不能调用mk_tcp_session_send/mk_tcp_session_send_safe函数
* @param session 会话处理对象
*/
void
API_CALL
on_mk_websocket_session_destory
(
mk_tcp_session
session
){
log_printf
(
LOG_LEV
,
"%s %d"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
));
websocket_user_data
*
user_data
=
(
websocket_user_data
*
)
mk_websocket_session_get_user_data
(
session
);
free
(
user_data
);
}
}
/**
/**
* 收到
websocket
客户端发过来的数据
* 收到
tcp
客户端发过来的数据
* @param session 会话处理对象
* @param session 会话处理对象
* @param data 数据指针
* @param data 数据指针
* @param len 数据长度
* @param len 数据长度
*/
*/
void
API_CALL
on_mk_
websocket_session_data
(
mk_tcp_session
session
,
const
char
*
data
,
int
len
){
void
API_CALL
on_mk_
tcp_session_data
(
uint16_t
server_port
,
mk_tcp_session
session
,
const
char
*
data
,
int
len
){
log_printf
(
LOG_LEV
,
"from %s %d, data[%d]: %s"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
),
len
,
data
);
log_printf
(
LOG_LEV
,
"from %s %d, data[%d]: %s"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
),
len
,
data
);
mk_tcp_session_send
(
session
,
"echo:"
,
0
);
mk_tcp_session_send
(
session
,
"echo:"
,
0
);
mk_tcp_session_send
(
session
,
data
,
len
);
mk_tcp_session_send
(
session
,
data
,
len
);
...
@@ -80,42 +76,132 @@ void API_CALL on_mk_websocket_session_data(mk_tcp_session session,const char *da
...
@@ -80,42 +76,132 @@ void API_CALL on_mk_websocket_session_data(mk_tcp_session session,const char *da
* 每隔2秒的定时器,用于管理超时等任务
* 每隔2秒的定时器,用于管理超时等任务
* @param session 会话处理对象
* @param session 会话处理对象
*/
*/
void
API_CALL
on_mk_
websocket_session_manager
(
mk_tcp_session
session
){
void
API_CALL
on_mk_
tcp_session_manager
(
uint16_t
server_port
,
mk_tcp_session
session
){
log_printf
(
LOG_LEV
,
"%s %d"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
));
log_printf
(
LOG_LEV
,
"%s %d"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
));
}
}
/**
/**
* on_mk_websocket_session_destory之前触发on_mk_websocket_session_err
* 一般由于客户端断开tcp触发
* 一般由于客户端断开tcp触发
* 本事件中可以调用mk_tcp_session_send_safe函数
* 本事件中可以调用mk_tcp_session_send_safe函数
* @param session 会话处理对象
* @param session 会话处理对象
* @param code 错误代码
* @param code 错误代码
* @param msg 错误提示
* @param msg 错误提示
*/
*/
void
API_CALL
on_mk_websocket_session_err
(
mk_tcp_session
session
,
int
code
,
const
char
*
msg
){
void
API_CALL
on_mk_tcp_session_disconnect
(
uint16_t
server_port
,
mk_tcp_session
session
,
int
code
,
const
char
*
msg
){
log_printf
(
LOG_LEV
,
"%s %d will destory: %d %s"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
),
code
,
msg
);
log_printf
(
LOG_LEV
,
"%s %d: %d %s"
,
mk_tcp_session_peer_ip
(
session
),(
int
)
mk_tcp_session_peer_port
(
session
),
code
,
msg
);
tcp_session_user_data
*
user_data
=
(
tcp_session_user_data
*
)
mk_tcp_session_get_user_data
(
session
);
free
(
user_data
);
}
}
static
int
flag
=
1
;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
static
void
s_on_exit
(
int
sig
){
typedef
struct
{
flag
=
0
;
mk_tcp_client
client
;
//下面你可以夹杂你的私货数据
char
your_some_useful_data
[
1024
];
int
count
;
}
tcp_client_user_data
;
/**
* tcp客户端连接服务器成功或失败回调
* @param client tcp客户端
* @param code 0为连接成功,否则为失败原因
* @param msg 连接失败错误提示
*/
void
API_CALL
on_mk_tcp_client_connect
(
mk_tcp_client
client
,
int
code
,
const
char
*
msg
){
log_printf
(
LOG_LEV
,
"connect result:%d %s"
,
code
,
msg
);
if
(
code
==
0
){
//连接上后我们发送一个hello world测试数据
mk_tcp_client_send
(
client
,
"hello world"
,
0
);
}
else
{
tcp_client_user_data
*
user_data
=
mk_tcp_client_get_user_data
(
client
);
mk_tcp_client_release
(
client
);
free
(
user_data
);
}
}
/**
* tcp客户端与tcp服务器之间断开回调
* 一般是eof事件导致
* @param client tcp客户端
* @param code 错误代码
* @param msg 错误提示
*/
void
API_CALL
on_mk_tcp_client_disconnect
(
mk_tcp_client
client
,
int
code
,
const
char
*
msg
){
log_printf
(
LOG_LEV
,
"disconnect:%d %s"
,
code
,
msg
);
//服务器主动断开了,我们销毁对象
tcp_client_user_data
*
user_data
=
mk_tcp_client_get_user_data
(
client
);
mk_tcp_client_release
(
client
);
free
(
user_data
);
}
/**
* 收到tcp服务器发来的数据
* @param client tcp客户端
* @param data 数据指针
* @param len 数据长度
*/
void
API_CALL
on_mk_tcp_client_data
(
mk_tcp_client
client
,
const
char
*
data
,
int
len
){
log_printf
(
LOG_LEV
,
"data[%d]:%s"
,
len
,
data
);
}
}
/**
* 每隔2秒的定时器,用于管理超时等任务
* @param client tcp客户端
*/
void
API_CALL
on_mk_tcp_client_manager
(
mk_tcp_client
client
){
tcp_client_user_data
*
user_data
=
mk_tcp_client_get_user_data
(
client
);
char
buf
[
1024
];
sprintf
(
buf
,
"on_mk_tcp_client_manager:%d"
,
user_data
->
count
);
mk_tcp_client_send
(
client
,
buf
,
0
);
if
(
++
user_data
->
count
==
5
){
//发送5遍后主动释放对象
mk_tcp_client_release
(
client
);
free
(
user_data
);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
test_server
(){
mk_tcp_session_events
events_server
=
{
.
on_mk_tcp_session_create
=
on_mk_tcp_session_create
,
.
on_mk_tcp_session_data
=
on_mk_tcp_session_data
,
.
on_mk_tcp_session_manager
=
on_mk_tcp_session_manager
,
.
on_mk_tcp_session_disconnect
=
on_mk_tcp_session_disconnect
};
mk_tcp_server_events_listen
(
&
events_server
);
mk_tcp_server_server_start
(
80
,
TCP_TYPE
);
}
void
test_client
(){
mk_tcp_client_events
events_clent
=
{
.
on_mk_tcp_client_connect
=
on_mk_tcp_client_connect
,
.
on_mk_tcp_client_data
=
on_mk_tcp_client_data
,
.
on_mk_tcp_client_disconnect
=
on_mk_tcp_client_disconnect
,
.
on_mk_tcp_client_manager
=
on_mk_tcp_client_manager
,
};
mk_tcp_client
client
=
mk_tcp_client_create
(
&
events_clent
,
TCP_TYPE
);
tcp_client_user_data
*
user_data
=
(
tcp_client_user_data
*
)
malloc
(
sizeof
(
tcp_client_user_data
));
user_data
->
client
=
client
;
user_data
->
count
=
0
;
mk_tcp_client_set_user_data
(
client
,
user_data
);
mk_tcp_client_connect
(
client
,
"121.40.165.18"
,
8800
,
3
);
//你可以连接127.0.0.1 80测试
//mk_tcp_client_connect(client, "127.0.0.1", 80, 3);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
char
ini_path
[
2048
]
=
{
0
};
char
ini_path
[
2048
]
=
{
0
};
strcpy
(
ini_path
,
argv
[
0
]);
strcpy
(
ini_path
,
argv
[
0
]);
strcat
(
ini_path
,
".ini"
);
strcat
(
ini_path
,
".ini"
);
mk_env_init1
(
0
,
0
,
1
,
ini_path
,
0
,
NULL
,
NULL
);
mk_env_init1
(
0
,
0
,
1
,
ini_path
,
0
,
NULL
,
NULL
);
mk_websocket_events
events
=
{
.
on_mk_websocket_session_create
=
on_mk_websocket_session_create
,
.
on_mk_websocket_session_destory
=
on_mk_websocket_session_destory
,
.
on_mk_websocket_session_data
=
on_mk_websocket_session_data
,
.
on_mk_websocket_session_manager
=
on_mk_websocket_session_manager
,
.
on_mk_websocket_session_err
=
on_mk_websocket_session_err
};
mk_websocket_events_listen
(
&
events
);
test_server
(
);
mk_websocket_server_start
(
80
,
0
);
test_client
(
);
signal
(
SIGINT
,
s_on_exit
);
// 设置退出信号
signal
(
SIGINT
,
s_on_exit
);
// 设置退出信号
while
(
flag
)
{
while
(
flag
)
{
...
...
src/Http/WebSocketClient.h
查看文件 @
11a7d1e6
...
@@ -348,21 +348,25 @@ public:
...
@@ -348,21 +348,25 @@ public:
/**
/**
* 重载startConnect方法,
* 重载startConnect方法,
* 目的是替换TcpClient的连接服务器行为,使之先完成WebSocket握手
* 目的是替换TcpClient的连接服务器行为,使之先完成WebSocket握手
* @param
strUrl
websocket服务器ip或域名
* @param
host
websocket服务器ip或域名
* @param iPort websocket服务器端口
* @param iPort websocket服务器端口
* @param fTimeOutSec 超时时间
* @param fTimeOutSec 超时时间
*/
*/
void
startConnect
(
const
string
&
strUrl
,
uint16_t
iPort
,
float
fTimeOutSec
=
3
)
override
{
void
startConnect
(
const
string
&
host
,
uint16_t
iPort
,
float
fTimeOutSec
=
3
)
override
{
string
ws_url
;
string
ws_url
;
if
(
useWSS
){
if
(
useWSS
){
//加密的ws
//加密的ws
ws_url
=
StrPrinter
<<
"wss://"
+
strUrl
<<
":"
<<
iPort
<<
"/"
;
ws_url
=
StrPrinter
<<
"wss://"
+
host
<<
":"
<<
iPort
<<
"/"
;
}
else
{
}
else
{
//明文ws
//明文ws
ws_url
=
StrPrinter
<<
"ws://"
+
strUrl
<<
":"
<<
iPort
<<
"/"
;
ws_url
=
StrPrinter
<<
"ws://"
+
host
<<
":"
<<
iPort
<<
"/"
;
}
}
_wsClient
->
startWsClient
(
ws_url
,
fTimeOutSec
);
_wsClient
->
startWsClient
(
ws_url
,
fTimeOutSec
);
}
}
void
startWebSocket
(
const
string
&
ws_url
,
float
fTimeOutSec
=
3
){
_wsClient
->
startWsClient
(
ws_url
,
fTimeOutSec
);
}
private
:
private
:
typename
HttpWsClient
<
ClientType
,
DataType
>::
Ptr
_wsClient
;
typename
HttpWsClient
<
ClientType
,
DataType
>::
Ptr
_wsClient
;
};
};
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论