janus_transport_task 创新一个线程用于处理异步的请求。
janus_transport_requests 创新一个线程处于进来的请求。
通过取配置的文件夹,读取里面的插件库文件while((pluginent = readdir(dir)))
+janus_plugin *janus_plugin = create(); 创建插件用来处理相应的插件操作。
通过取配置的文件夹,读取里面的通信库文件while((transportent = readdir(dir)))
+janus_transport *janus_transport = create();
如图所示为基本框图:
创建线程janus_transport_requests,这个线程用来处理进来的请求。通过从队列requests中不断取得请求,调用janus_process_incoming_request进行异处处理与响应。
GThread *requests_thread = g_thread_try_new(“sessions requests”, &janus_transport_requests, NULL, &error);
当收到http请求时,调用函数janus_http_handler,如果是websocket,那么通过回调函数:janus_websockets_common_callback里的LWS_CALLBACK_RECEIVE:
gateway->incoming_request(&janus_websockets_transport, ws_client->ts, NULL, admin, root, &error);
在函数中调用 网关的static janus_transport_callbacks *gateway = NULL;
gateway->incoming_request(&janus_http_transport, ts, ts, FALSE, root, &error);
incoming_request指针函数指向janus_transport_incoming_request
进而g_async_queue_push(requests, request);压入请求,给后面异步处理。
void janus_transport_incoming_request(janus_transport *plugin,
janus_transport_session *transportr) {
janus_request *request = janus_request_new(plugin, transport,
request_id, admin, message);
g_async_queue_push(requests, request);
}
在队列中的请求,这里创建独立的线程来过行处理。
GThread *requests_thread = g_thread_try_new("sessions requests",
&janus_transport_requests, NULL, &error);
tasks = g_thread_pool_new(janus_transport_task, NULL, -1, FALSE,
&error);
janus_transport_requests 用来处理刚刚压入队列的请求。
request = g_async_queue_pop(requests);
拿到请求后调用janus_process_incoming_request进行处理。
其中某一个功能是:调用janus_session_create创建线程。创建成功调用janus_process_success发送响应信息。
当线程创建成功后,在janus_process_incoming_request函数可以处理不同的请求命令。例如:attach, plugin,destroy等。
janus_process_incoming_request
json_t *transaction = json_object_get(root, "transaction");
const gchar *transaction_text = json_string_value(transaction);
json_t *message = json_object_get(root, "janus");
if(session_id == 0 && handle_id == 0) {//创建线程
session = janus_session_create(session_id);
request->transport->session_created
ret = janus_process_success(request, reply);//创建响应
//janus_process_success用来发送响应信息到对应的网络接口。
//**调用send_message指针函数 request->transport->send_message,
//在websocket接口中实际调用:janus_websockets_send_message**
}
if(!strcasecmp(message_text, "keepalive"))//处理keepalive
if(!strcasecmp(message_text, "attach")) //处理attach,加载插件。
{
json_t *plugin = json_object_get(root, "plugin");
const gchar *plugin_text = json_string_value(plugin);
janus_plugin *plugin_t = janus_plugin_find(plugin_text);
}
if(!strcasecmp(message_text, "hangup"))
if(!strcasecmp(message_text, "message"))
{
json_t *body = json_object_get(root, "body");
/* Is there an SDP attached? */
json_t *jsep = json_object_get(root, "jsep");
janus_sdp *parsed_sdp = janus_sdp_preparse(jsep_sdp
}
janus_websockets_send_message把响应的信息通过此函数推到队列中,并且执行lws_callback_on_writable(client->wsi);启动janus_websockets_common_callback回调。
int janus_websockets_send_message(janus_transport_session *transport, void *request_id, gboolean admin, json_t *message) {
if(message == NULL)
return -1;
if(transport == NULL || g_atomic_int_get(&transport->destroyed)) {
json_decref(message);
return -1;
}
janus_mutex_lock(&transport->mutex);
janus_websockets_client *client = (janus_websockets_client *)transport->transport_p;
if(!client) {
json_decref(message);
janus_mutex_unlock(&transport->mutex);
return -1;
}
/* Convert to string and enqueue */
char *payload = json_dumps(message, json_format);
g_async_queue_push(client->messages, payload);
lws_callback_on_writable(client->wsi);
janus_mutex_unlock(&transport->mutex);
json_decref(message);
return 0;
}
janus_websockets_common_callback队列中的信息通过此函数来直接发送出去。
static int janus_websockets_common_callback(
struct lws *wsi,
enum lws_callback_reasons reason,
void *user, void *in, size_t len, gboolean admin)
{
const char *log_prefix = admin ? "AdminWSS" : "WSS";
janus_websockets_client *ws_client = (janus_websockets_client *)user;
switch(reason) {
case LWS_CALLBACK_RECEIVE:
gateway->incoming_request(&janus_websockets_transport, ws_client->ts, NULL, admin, root, &error);
case LWS_CALLBACK_SERVER_WRITEABLE:
char *response = g_async_queue_try_pop(ws_client->messages);
memcpy(ws_client->buffer + LWS_SEND_BUFFER_PRE_PADDING, response, strlen(response));
JANUS_LOG(LOG_HUGE, "[%s-%p] Sending WebSocket message (%zu bytes)...\n", log_prefix, wsi, strlen(response));
int sent = lws_write(wsi, ws_client->buffer + LWS_SEND_BUFFER_PRE_PADDING, strlen(response), LWS_WRITE_TEXT);
}
janus_ice_cb_nice_recv 被调用
janus_plugin *plugin = (janus_plugin *)handle->app;
if(plugin && plugin->incoming_rtp &&
gateway->relay_rtp(handle, video, buf, len);
插件指针函数
static janus_plugin janus_echotest_plugin =
JANUS_PLUGIN_INIT (
.init = janus_echotest_init,
.destroy = janus_echotest_destroy,
.get_api_compatibility =janus_echotest_get_api_compatibility,
.get_version = janus_echotest_get_version,
.get_version_string = janus_echotest_get_version_string,
.get_description = janus_echotest_get_description,
.get_name = janus_echotest_get_name,
.get_author = janus_echotest_get_author,
.get_package = janus_echotest_get_package,
.create_session = janus_echotest_create_session,
.handle_message = janus_echotest_handle_message,
.setup_media = janus_echotest_setup_media,
.incoming_rtp = janus_echotest_incoming_rtp,
.incoming_rtcp = janus_echotest_incoming_rtcp,
.incoming_data = janus_echotest_incoming_data,
.slow_link = janus_echotest_slow_link,
.hangup_media = janus_echotest_hangup_media,
.destroy_session = janus_echotest_destroy_session,
.query_session = janus_echotest_query_session,
);