互联网直播点播平台go语言搭建重定向和反向代理的区别及使用
时间:2022-07-22
本文章向大家介绍互联网直播点播平台go语言搭建重定向和反向代理的区别及使用,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在我们进行视频直播点播流媒体服务器EasyDSS的开发过程中,用户端和资源服务器需要一个数据请求和返还的过程,数据请求成功,资源才能被获取到,从而正确显示。
我们的研发存在下图架构模式:后台服务程序和资源不在同一个机器中。
如上图所示,Browser 为用户端。Server 为服务端,Resource 为资源服务器。Server 服务端做为中间桥梁,用户端需要获取资源的话,需要先向服务端请求数据,通过服务端拉取资源,再返还给用户端。
对于普通的资源文件,如图片等,采用重定向的方式。以Gin框架为例:
c.Redirect(http.StatusFound, realResourcelUrl)
重定向的基本流程为:
- 浏览器端发送获取资源请求,请求地址为 resourceUrl
- 服务端接收到请求后,对 resourceUrl 进行重定向,将 realResourceUrl 返回给浏览器端
- 浏览器端获取服务端将 resourceUrl 重定向,向资源服务器发送获取 realResourceUrl 的请求,获取到最终的资源显示到浏览器中。
重定向的方式不会过度的消耗服务器的资源,但是在某些情况下,还仍使用反向代理的方式进行资源的获取。
反向代理的基本流程为:
- 浏览器端发送获取资源请求,请求地址为 resourceUrl;
- 服务端收到获取资源请求后,向资源服务器发送 realResourceUrl 请求;
- 服务端获取到真实的资源后,将对应的资源返回给浏览器端。
反向代理过程中,浏览器端并不知道资源是存储在另一台资源服务器中。此种方法虽然隐藏了资源服务器,但是会消耗服务器的资源。 在开发视频播放网站时,如果浏览器端的播放器不支持重定向功能,那么就必须采用反向代理的方式进行开发。一般情况下浏览器播放器均不支持重定向功能。
Go 语言中的反向代理示例代码如下:
func Handler() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
recover()
}()
target := fmt.Sprintf("%s:%v", cluster.GetFlvLocalIp(strings.TrimSuffix(flvName, ".flv")), dss.GetHTTPPort())
director := func(req *http.Request) {
req.URL.Scheme = "http"
req.URL.Host = target
req.URL.Path = strings.Replace(req.URL.Path, consts.RouteHTTPFLV, consts.EmptyString, 1)
}
tranport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
}
errHandle := func(res http.ResponseWriter, req *http.Request, err error) {
log.Println("proxy is error : ", err)
c.AbortWithError(http.StatusVariantAlsoNegotiates, err)
}
proxy := &httputil.ReverseProxy{
Director: director,
Transport: tranport,
ErrorHandler: errHandle,
}
c.Request.URL.RawQuery = q.Encode()
proxy.ServeHTTP(c.Writer, c.Request)
c.Next()
return
}
c.AbortWithStatusJSON(http.StatusUnauthorized,
consts.MsgErrorUnauthorized)
return
}
}
- ajax 设置Access-Control-Allow-Origin实现跨域访问
- gradle新建工程,多项目依赖,聚合工程
- Apache Hive-2.3.0 快速搭建与使用
- HBase-1.3.1 集群搭建 - 报错整理
- 分布式唯一ID生成器Twitter 的 Snowflake idworker java版本
- 使用 Phoenix-4.11.0连接 Hbase 集群 ,并使用 JDBC 查询测试
- 高并发分布式系统中生成全局唯一Id汇总
- ZooKeeper 可视化监控 zkui
- 关于RBAC(Role-Base Access Control)的理解
- Spring Boot 中使用 Kafka
- 如何评价一段代码
- java系统高并发的解决方案
- Spring Boot 中使用 Redis
- 使用 Jedis 连接操作 Redis
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java自动化测试(web自动化测试框架 28)
- 你想要拥有自己的搜索引擎吗?
- JAVA三年面试总结,金九银十,你准备好了吗?
- Best Cow Line(POJ 3617)
- Flask单点登录竟然只要几行代码就能搞定!
- 区间调度问题
- 迷宫的最短路径
- Lake Counting (POJ No.2386)
- 部分和问题(DFS)
- 为什么 React Hooks useState 更新不符预期?
- 技术分享 | MySQL 使用 MariaDB 审计插件
- 第12期:压缩表性能监测
- 第05期:使用 prometheus 监控 clickhouse 集群
- 这 6 点知识让我对 JavaScript 的对象有了更进一步的了解
- Linux进程间通信(中)之信号、信号量实践