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

相关文章

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

MySQL 临时表与复制表操作全流程案例

《MySQL临时表与复制表操作全流程案例》本文介绍MySQL临时表与复制表的区别与使用,涵盖生命周期、存储机制、操作限制、创建方法及常见问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小... 目录一、mysql 临时表(一)核心特性拓展(二)操作全流程案例1. 复杂查询中的临时表应用2. 临时

MySQL 升级到8.4版本的完整流程及操作方法

《MySQL升级到8.4版本的完整流程及操作方法》本文详细说明了MySQL升级至8.4的完整流程,涵盖升级前准备(备份、兼容性检查)、支持路径(原地、逻辑导出、复制)、关键变更(空间索引、保留关键字... 目录一、升级前准备 (3.1 Before You Begin)二、升级路径 (3.2 Upgrade

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具