NuPlayer从服务端获取应答消息流程

2024-06-04 03:08

本文主要是介绍NuPlayer从服务端获取应答消息流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  本文具体介绍NuPlayer获取应答消息的代码流程,流程设计到的每一个行数的详细介绍在之前的文章都有介绍。
  下一篇文章介绍接收到服务端发送来的应答消息后的处理过程:
  ARTSPConnection::notifyResponseListener函数完成这个流程。
  

==>
void ARTSPConnection::performConnect(const sp<AMessage> &reply,AString host, unsigned port) {struct hostent *ent = gethostbyname(host.c_str());if (ent == NULL) {ALOGE("Unknown host %s", host.c_str());reply->setInt32("result", -ENOENT);reply->post();mState = DISCONNECTED;return;}mSocket = socket(AF_INET, SOCK_STREAM, 0);if (mUIDValid) {HTTPBase::RegisterSocketUserTag(mSocket, mUID,(uint32_t)*(uint32_t*) "RTSP");HTTPBase::RegisterSocketUserMark(mSocket, mUID);}MakeSocketBlocking(mSocket, false);struct sockaddr_in remote;memset(remote.sin_zero, 0, sizeof(remote.sin_zero));remote.sin_family = AF_INET;remote.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;remote.sin_port = htons(port);int err = ::connect(mSocket, (const struct sockaddr *)&remote, sizeof(remote));reply->setInt32("server-ip", ntohl(remote.sin_addr.s_addr));if (err < 0) {if (errno == EINPROGRESS) {sp<AMessage> msg = new AMessage(kWhatCompleteConnection, this);msg->setMessage("reply", reply);msg->setInt32("connection-id", mConnectionID);msg->post();return;}reply->setInt32("result", -errno);mState = DISCONNECTED;if (mUIDValid) {HTTPBase::UnRegisterSocketUserTag(mSocket);HTTPBase::UnRegisterSocketUserMark(mSocket);}close(mSocket);mSocket = -1;} else {reply->setInt32("result", OK);mState = CONNECTED;mNextCSeq = 1;//==>postReceiveReponseEvent();}reply->post();
} ==>
void ARTSPConnection::postReceiveReponseEvent() {if (mReceiveResponseEventPending) {return;}sp<AMessage> msg = new AMessage(kWhatReceiveResponse, this);msg->post();mReceiveResponseEventPending = true;
} ==>
void ARTSPConnection::onMessageReceived(const sp<AMessage> &msg) {switch (msg->what()) {case kWhatConnect:onConnect(msg);break;case kWhatDisconnect:onDisconnect(msg);break;case kWhatCompleteConnection:onCompleteConnection(msg);break;case kWhatSendRequest:onSendRequest(msg);break;case kWhatReceiveResponse://==>onReceiveResponse();break;case kWhatObserveBinaryData:{CHECK(msg->findMessage("reply", &mObserveBinaryMessage));break;}default:TRESPASS();break;}
}==>
void ARTSPConnection::onReceiveResponse() {mReceiveResponseEventPending = false;if (mState != CONNECTED) {return;}struct timeval tv;tv.tv_sec = 0;tv.tv_usec = kSelectTimeoutUs;fd_set rs;FD_ZERO(&rs);FD_SET(mSocket, &rs);int res = select(mSocket + 1, &rs, NULL, NULL, &tv);if (res == 1) {MakeSocketBlocking(mSocket, true);//==>bool success = receiveRTSPReponse();MakeSocketBlocking(mSocket, false);if (!success) {// Something horrible, irreparable has happened.flushPendingRequests();return;}}postReceiveReponseEvent();
}==>
bool ARTSPConnection::receiveRTSPReponse() {AString statusLine;if (!receiveLine(&statusLine)) {return false;}if (statusLine == "$") {sp<ABuffer> buffer = receiveBinaryData();if (buffer == NULL) {return false;}if (mObserveBinaryMessage != NULL) {sp<AMessage> notify = mObserveBinaryMessage->dup();notify->setBuffer("buffer", buffer);notify->post();} else {ALOGW("received binary data, but no one cares.");}return true;}sp<ARTSPResponse> response = new ARTSPResponse;response->mStatusLine = statusLine;ALOGI("status: %s", response->mStatusLine.c_str());ssize_t space1 = response->mStatusLine.find(" ");if (space1 < 0) {return false;}ssize_t space2 = response->mStatusLine.find(" ", space1 + 1);if (space2 < 0) {return false;}bool isRequest = false;if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) {CHECK(IsRTSPVersion(AString(response->mStatusLine,space2 + 1,response->mStatusLine.size() - space2 - 1)));isRequest = true;response->mStatusCode = 0;} else {AString statusCodeStr(response->mStatusLine, space1 + 1, space2 - space1 - 1);if (!ParseSingleUnsignedLong(statusCodeStr.c_str(), &response->mStatusCode)|| response->mStatusCode < 100 || response->mStatusCode > 999) {return false;}}AString line;ssize_t lastDictIndex = -1;for (;;) {if (!receiveLine(&line)) {break;}if (line.empty()) {break;}ALOGV("line: '%s'", line.c_str());if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {// Support for folded header values.if (lastDictIndex < 0) {// First line cannot be a continuation of the previous one.return false;}AString &value = response->mHeaders.editValueAt(lastDictIndex);value.append(line);continue;}ssize_t colonPos = line.find(":");if (colonPos < 0) {// Malformed header line.return false;}AString key(line, 0, colonPos);key.trim();key.tolower();line.erase(0, colonPos + 1);lastDictIndex = response->mHeaders.add(key, line);}for (size_t i = 0; i < response->mHeaders.size(); ++i) {response->mHeaders.editValueAt(i).trim();}unsigned long contentLength = 0;ssize_t i = response->mHeaders.indexOfKey("content-length");if (i >= 0) {AString value = response->mHeaders.valueAt(i);if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) {return false;}}if (contentLength > 0) {response->mContent = new ABuffer(contentLength);if (receive(response->mContent->data(), contentLength) != OK) {return false;}}if (response->mStatusCode == 401) {if (mAuthType == NONE && mUser.size() > 0&& parseAuthMethod(response)) {ssize_t i;CHECK_EQ((status_t)OK, findPendingRequest(response, &i));CHECK_GE(i, 0);sp<AMessage> reply = mPendingRequests.valueAt(i);mPendingRequests.removeItemsAt(i);AString request;CHECK(reply->findString("original-request", &request));sp<AMessage> msg = new AMessage(kWhatSendRequest, this);msg->setMessage("reply", reply);msg->setString("request", request.c_str(), request.size());ALOGI("re-sending request with authentication headers...");onSendRequest(msg);return true;}}//==>return isRequest? handleServerRequest(response): notifyResponseListener(response);
}==>
bool ARTSPConnection::notifyResponseListener(const sp<ARTSPResponse> &response) {ssize_t i;status_t err = findPendingRequest(response, &i);if (err == OK && i < 0) {// An unsolicited server response is not a problem.return true;}if (err != OK) {return false;}sp<AMessage> reply = mPendingRequests.valueAt(i);mPendingRequests.removeItemsAt(i);reply->setInt32("result", OK);reply->setObject("response", response);reply->post();return true;
}

这篇关于NuPlayer从服务端获取应答消息流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028892

相关文章

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

使用Python实现获取屏幕像素颜色值

《使用Python实现获取屏幕像素颜色值》这篇文章主要为大家详细介绍了如何使用Python实现获取屏幕像素颜色值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、一个小工具,按住F10键,颜色值会跟着显示。完整代码import tkinter as tkimport pyau

Python FastMCP构建MCP服务端与客户端的详细步骤

《PythonFastMCP构建MCP服务端与客户端的详细步骤》MCP(Multi-ClientProtocol)是一种用于构建可扩展服务的通信协议框架,本文将使用FastMCP搭建一个支持St... 目录简介环境准备服务端实现(server.py)客户端实现(client.py)运行效果扩展方向常见问题结

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1