视频谈话记录和直播系统的实现二blazor+srs+nginx开发和运行环境搭建
本文涉及到的主要技术框架、开源软件有:.netcore blazor srs ffmpeg nginx javascript efcore
引言
上篇对设计目标和技术原型进行了初步测试,证明思路是可行的,本篇开始着手实现,并记录其中的要点。
为什么选中Blazor
选择的理由有一百种,不选择的理由就有一万种。- 熟悉:C#和asp net core是个人相对熟悉的技术,开发起来较为顺手 。刚开始接触blazor的话,会有一些vue的感觉。
在blazor项目中,大部分时间不用写js,如果你做的是全栈开发,就不用像以前一样在c#和js中来回穿梭了,这种行云流水的开发体验,是其他框架和工具没有的。当然,blazor和js交互也是完全没有问题的。
SignalR用在这种对实时性要求较高的项目中再合适不过了,而blazo对SignalR天然支持。
关于生产环境
为了方便,开发过程中使用了Sqlite,在生产环境中,建议MySql或者SqlServer。服务器操作系统建议Ubuntu、debian、centos,以及国产操作系统对应的服务器版本,或者也可以分开部署。
虽然整个项目运行在windows上没有任何问题,但还是有一些细小的差别。比如:srs的webrtc推流默认采用udp方式,在实际测试中,发现有很大概率出现丢包,会导致直播卡顿,录像丢失片段,这是不能容忍的,这个问题在srs5.0.60中已经得到了解决,可以选择采用tcp协议传输。但由于官方的windows版本目前还停留在5.0.19,并不包含这个新的特性。
此外,关于性能和安全方面的问题,已经讨论的足够多了,这里不再赘述。
要点记录
在Blazor Server项目中引入Ant Design Of Blazor
blazor自身有一些基础组件,可以基于它们实现自己的组件库,也可以引用一些开源项目,可选择的范围还是比较广泛的,比如MASA Blazor、Ant Design of Blazor、Bootstrap Blazor。在这个项目中,笔者选择了Ant Design of Blazor。
- 在项目上右击。选择“管理NuGet程序包”,搜索“AntDesign”安装即可。
- 在Program.cs中注入服务:
builder.Services.AddAntDesign();
- 在_Layout.cshtml中,引入
<link href="_content/AntDesign/css/ant-design-blazor.css" rel="stylesheet" />
<script src="_content/AntDesign/js/ant-design-blazor.js"></script>
- 没错,就这么简单,组件使用文档请参阅官网。
IHostedService的注入
在asp.net core中,这个神奇的接口,能让你在程序正式启动前运行自己的业务逻辑,比如检测系统启动的环境、构建基础数据、检测授权信息等。在本项目中,主要是实现启动srs和nginx。
- 新建一个cs类,继承IHostedService接口。
public class MyInitAppService : IHostedService
{
public MyInitAppService(IDbContextFactory<MyDataContext> dbContextFactory)
{
//根据需要注入EF Core数据工厂
}
}
- 在StartAsync或者构造函数中编写启动代码。
public Task StartAsync(CancellationToken cancellationToken)
{
try
{
Console.WriteLine("清理my-srs和my-nginx进程");
Process[] processes = System.Diagnostics.Process.GetProcesses();
foreach (Process item in processes)
{
if (item.ProcessName.Contains("my-srs") || item.ProcessName.Contains("my-nginx"))
{
item.Kill();
}
}
Thread.Sleep(2000);
}
catch
{
}
Console.WriteLine("启动必需的第三方软件,目标平台:" Environment.OSVersion.Platform);
Console.WriteLine("启动:srs");
try
{
Task.Run(() => {
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = @"srs-win\my-srs.exe";
info.Arguments = @"-c conf\rtc.conf";
info.WorkingDirectory = AppContext.BaseDirectory "srs-win";
info.UseShellExecute = false;
info.CreateNoWindow = true;
Process p = new Process();
p.StartInfo = info;
p.Start();
});
}
catch (Exception ex)
{
Console.WriteLine("srs启动失败,部分功能无法使用,可能是:" ex.Message);
}
Console.WriteLine("启动:nginx");
try
{
Task.Run(() =>
{
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = @"nginx-win\my-nginx.exe";
info.WorkingDirectory = AppContext.BaseDirectory "nginx-win";
info.UseShellExecute = false;
info.CreateNoWindow = false;
Process p = new Process();
p.StartInfo = info;
p.Start();
});
}
catch (Exception ex)
{
Console.WriteLine("nginx启动失败,部分功能无法使用,可能是:" ex.Message);
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
//停止时终止srs和nginx
try
{
Console.WriteLine("清理my-srs和my-nginx进程");
Process[] processes = System.Diagnostics.Process.GetProcesses();
foreach (Process item in processes)
{
if (item.ProcessName.Contains("my-srs") || item.ProcessName.Contains("my-nginx"))
{
item.Kill();
}
}
Thread.Sleep(2000);
}
catch { }
return Task.CompletedTask;
}
不要完全依赖于StopAsync,因为只有通过Ctrl C正常退出时才会执行这个方法。
3. 测试一下,当然是顺利启动了,从任务管理器中可以看到这两个进程。
4.在实际项目中,可以从数据库读取srs和nginx的配置,动态生成conf文件,可以避免和系统中已经存在的组件发生端口冲突。
WebRTC推流的前提:HTTPS通信
使用nginx的最基本的意图,就是把srs和blazor server的端口统一进行代理,从而实现https通信。因为webrtc仅支持localhost和https。
nginx的配置要点如下:
http {
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
include mime.types;
default_type application/octet-stream;
sendfile on;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
#keepalive_timeout 65;
#gzip on;
server {
listen 5200 ssl default http2;
charset utf-8;
ssl_certificate my.com.crt;
ssl_certificate_key my.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
location / {
#代理blazor server端口
proxy_pass http://127.0.0.1:5201;
#下面几行是为signalr配置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location ~ ^/(api|rtc)/ {
#代理srs http api端口
proxy_pass http://127.0.0.1:5285$request_uri;
}
location /live/ {
#代理srs http端口
proxy_pass http://127.0.0.1:5288/live/;
}
}
}
通过上面的配置,就实现了一个证书,通吃所有通信。同时,也为后期负载均衡、故障转移等留了余地。
这个证书是自签名的,所以浏览器会出现风险提示,用户只要允许访问即可,不影响正常使用。当然,如果客户网络中有自己的dns系统,就可以申请一个域名证书,避免出现这样的提示。
其实,srs自身也是支持https的,但由于使用了自签名证书,在推流时默认是拒绝访问的,需要再有一次交互过程。
在Blazor组件中模块化加载JavaScript
blazor组件中嵌入js脚本的方式有几种,最简单的是在_layout.cshtml直接引入,但是这种方式会导致每个blazor组件都会加载这些脚本,延长客户端加载时间,并且极易产生变量污染。比较理想的做法是模块化加载,也就是每个blazor只加载和自己相关的js文件。
[Inject] IJSRuntime _js { get; set; } //注入依赖
//在首次渲染时加载js文件
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
{
jsModule = await _js.InvokeAsync<IJSObjectReference>("import", "./js/TalkingPlayer.js"); //TalkingPlayer.js放在wwwroot/js下
}
}
调用也很简单:
//res接收返回结果
var res = await jsModule.InvokeAsync<string>("start", "这是参数"); // start是js中的方法名称
js中的start方法需要export
export async function start(arg) {
console.log("接受到的参数:" arg);
return "调用成功";
}
下一篇,将处理一些意外情况。
原型测试代码下载地址
已经上传到资源下载。传送门在此。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggabff
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01