Avalonia 实现视频聊天、远程桌面(源码,支持Windows、Linux、国产OS)
现在最火的.NET跨平台UI框架莫过于Avalonia了。Avalonia 基于.NET Core,因此它可以运行在任何支持.NET Core的平台上。之前基于CPF跨平台UI框架写过一个视频聊天的demo,而现在看来Avalonia是大势所趋,于是,我再写一个Avalonia版本的Demo来供大家参考,它可以在Windows和Linux(包括国产OS,如银河麒麟、统信UOS)上运行。
下图是视频聊天Demo的Avalonia客户端在国产统信UOS上的运行的截图:

一.功能介绍
客户端登录成功后,运行的主界面如下图所示:

1. 视频聊天
(1)每个登录的用户都可向其他任意在线用户发送视频聊天请求。
(2)当收到来自其他在线用户的视频聊天邀请时,可接受或拒绝对方的请求。
(3)当接受其他在线用户的视频聊天邀请时,即可开启视频聊天。
2. 远程桌面
(1)每个登录的用户都可向其他任意在线用户发送远程桌面请求;当对方未响应时,可主动取消远程桌面请求。
(2)当收到来自其他在线用户请求控制桌面时,可接受或拒绝对方的请求。
(3)当发送方收到其他在线用户同意控制其电脑时,即可开启远程桌面连接。
(4)被控端和主控端都可主动断开远程桌面连接。
二.开发环境
1.开发工具:
Visual Studio 2022
2. 开发框架:
.NET Core 3.1
3.开发语言:
C#
4.其它框架:
Avalonia UI 框架(版本:0.10.22)、OMCS 语音视频框架 (版本:8.0)
注:建议 Avalonia 使用0.10.*的版本,精简而且很稳定,而最新的11.0的版本太庞大了。
三.具体实现
下面我们讲一下Demo中核心的代码实现,大家从文末下载源码并对照着源码看,会更清楚些。
1.自定义消息类型 InformationTypes
public static class InformationTypes
{
/// <summary>
/// 视频请求 0
/// </summary>
public const int VideoRequest = 0; /// <summary>
/// 回复视频请求的结果 1
/// </summary>
public const int VideoResult = 1; /// <summary>
/// 通知对方 挂断 视频连接 2
/// </summary>
public const int CloseVideo = 2; /// <summary>
/// 通知好友 网络原因,导致 视频中断 3
/// </summary>
public const int NetReasonCloseVideo = 3; /// <summary>
/// 通知对方(忙线中) 挂断 视频连接 4
/// </summary>
public const int BusyLine = 4; /// <summary>
/// 远程桌面请求 5
/// </summary>
public const int DesktopRequest = 5; /// <summary>
/// 回复远程桌面请求的结果 6
/// </summary>
public const int DesktopResult = 6; /// <summary>
/// 主动取消远程桌面请求 7
/// </summary>
public const int CancelDesktop = 7; /// <summary>
/// 对方(主人端)主动断开远程桌面 8
/// </summary>
public const int OwnerCloseDesktop = 8; /// <summary>
/// 客人端断开远程桌面连接 9
/// </summary>
public const int GuestCloseDesktop = 9;
}
2. 发送视频请求
(1)当发起视频聊天时,将显示视频聊天窗口
/// <summary>
/// 打开视频通话窗口
/// </summary>
/// <param name="destID">对方ID</param>
/// <param name="isWorking">false表示主动发起视频通话邀请</param>
internal void OpenVideoChat(string destID,bool isWorking)
{
if (!this.VideoInvokeVerdict(destID))
{
return;
} App.Multimedia.OutputAudio = true;
VideoChatWindow videoChatWindow = new VideoChatWindow(destID, isWorking);
videoChatWindow.EndTheCalled += VideoChatWindow_EndTheCalled;
objectManager.Add(destID, videoChatWindow);
videoChatWindow.Show();
}
(2)连接自己的摄像头
public VideoChatWindow(string destID,bool isWorking)
{
this.DestID = destID;
this.IsWorking = isWorking;
InitializeComponent(); //连接自己的摄像头
this.selfCamera.Core.DisplayVideoParameters = true;
this.selfCamera.Core.VideoDrawMode = VideoDrawMode.ScaleToFill;
this.selfCamera.BeginConnect(MainWindow.CurrentID); this.Title = this.title.Text = this.RepeatedCallTip(false);
this.timer = new System.Timers.Timer();
this.timer.Interval = 1000;
this.timer.Elapsed += Timer_Elapsed;
if (IsWorking)
{
this.BeginConnect();
}
}
(3)发送视频通话请求
protected override void OnInitialized()
{
base.OnInitialized();
this.SetWindowStats();
if (!this.IsWorking)
{
//向对方发起视频通话邀请
VideoController.Singleton.SendMessage(this.DestID, InformationTypes.VideoRequest, null);
}
}
3. 回复对方视频请求
(1)当收到对方的视频聊天邀请时,将显示视频邀请窗口

(2)发送回复视频聊天请求消息
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (this.EndTheCalled != null)
{
this.EndTheCalled(this.DestID);
}
if (this.NotifyOther)
{
//回复对方的视频通话请求
byte[] bytes = BitConverter.GetBytes(replyResult);
VideoController.Singleton.SendMessage(this.DestID, InformationTypes.VideoResult, bytes);
}
if (this.replyResult)
{
VideoController.Singleton.OpenVideoChat(DestID,true);
}
}
4. 收到对方视频请求的回复
/// <summary>
/// 视频通话,收到对方回复
/// </summary>
internal void TargerReply(string destID, CommunicationStateType type)
{
ICommunicationAid aid = this.objectManager.Get(destID);
if(aid == null)
{
return;
}
switch (type)
{
case CommunicationStateType.Agree:
VideoChatWindow videoChatWindow = (VideoChatWindow)aid;
videoChatWindow.BeginConnect();
break;
case CommunicationStateType.Reject:
aid.CloseWindow(false);
break;
case CommunicationStateType.HangUp:
aid.CloseWindow(false);
break;
default:
break;
}
}
当对方回复同意时,将连接到对方的麦克风和摄像头,开始视频聊天会话:
/// <summary>
/// 连接对方设备
/// </summary>
internal void BeginConnect()
{
UiSafeInvoker.ActionOnUI(() =>
{
this.IsWorking = true;
this.Title = this.title.Text = this.RepeatedCallTip(false);
this.startTime = DateTime.Now;
this.timer.Start();
this.otherCamera.Core.DisplayVideoParameters = true;
this.otherCamera.Core.VideoDrawMode = VideoDrawMode.ScaleToFill;
this.otherCamera.Core.ConnectEnded += DynamicCameraConnector_ConnectEnded;
this.otherCamera.Core.Disconnected += DynamicCameraConnector_Disconnected;
this.microphoneConnector.ConnectEnded += MicrophoneConnector_ConnectEnded;
this.microphoneConnector.Disconnected += MicrophoneConnector_Disconnected;
this.otherCamera.BeginConnect(this.DestID);
this.microphoneConnector.BeginConnect(this.DestID); this.NotifyOther = true;
});
}
5. 实现远程桌面
远程桌面的请求/应答逻辑几乎与视频聊天请求/应答逻辑是一模一样的。这里就不再罗列响应的代码了。
(1)当收到对方的远程桌面控制请求时,将显示请求窗口。

(2)当同意对方的控制请求时,对方就可以控制请求方的电脑了。

四.源码下载
.NetCore服务端 + Avalonia客户端:VideoChatMini.Avalonia.rar
在Windows上部署运行服务端和客户端很容易,大家也都很熟悉了。下面讲一下如何在Linux上部署运行这个视频聊天程序的服务端和客户端。
在Linux上部署运行说明
在部署之前,需要在linux服务端和客户端上分别安装 .Net core 3.1版本,命令行安装命令如下:
yum install dotnet-sdk-3.1
检查版本安装情况
dotnet --version
运行:
(1)在CentOS上启动VideoChatMini.ServerNetcore服务端:
拷贝Oraycn.VideoChatMini.ServerNetcore项目下的Debug文件夹,到CentOS操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动服务端
dotnet Oraycn.VideoChatMini.ServerNetcore.dll
(2)在麒麟或统信UOS、Ubuntu上运行VideoChatMini.ClientAvalonia客户端:
拷贝Oraycn.VideoChatMini.ClientAvalonia项目下的Debug文件夹,到麒麟或统信UOS、Ubuntu操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动客户端
dotnet Oraycn.VideoChatMini.ClientAvalonia.dll
命令执行成功后,就会出现之前截图的客户端主界面。
Avalonia 支持在X64和ARM64架构的Linux上运行,Demo的运行目录下放的是X64架构的so,如果需要ARM64架构的so,可留下邮箱获取。
Avalonia 实现视频聊天、远程桌面(源码,支持Windows、Linux、国产OS)的更多相关文章
- SSH客户端,FinalShell服务器管理,远程桌面加速软件,支持Windows,Mac OS X,Linux,版本2.6.3.1
FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还是功能强大的开发,运维工具,充分满足开发,运维需求. 用户QQ群 342045988 Windows版下载地址:http:/ ...
- pycharm2020.2破解版教程激活码支持Windows Linux Mac系统-中关村老大爷
听说很多朋友想要PyCharm专业版2020.2的破解教程.现在来了,亲测破解成功.支持mac linux windows系统.本教程提供官方安装包.激活码和注册补丁. 本教程仅供学习和讨论,禁止商业 ...
- QQ2008自动聊天精灵delphi源码
QQ2008自动聊天精灵delphi源码 unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Grap ...
- 修改Cosbench源码 支持s3的 http range request 测试场景
在视频点播的业务应用场景中,用户使用了ffmpeg工具做视频实时转码用. 而ffmpeg使用range 请求.而Cosbench不支持这种测试场景,所以需要修改源码支持这种测试场景. HTTP 协议介 ...
- 远程桌面连接不上|windows server 2003 sp2 termdd.sys(转载)
远程桌面连接不上|windows server 2003 sp2 termdd.sys.请教一个问题,为什么 Windows Server 2003 打上SP2补丁,就不能通过远程桌面连接上去了?服务 ...
- Azure VM对远程桌面登录的支持-示例
我们在开发Windows Azure的应用程序,虽然在大部分的情况下都可以使用Azure Emulator模拟器来模拟在云端计算节点(Azure VM)的执行结果,但是并不能100%模拟真正在Azur ...
- Python3.7源码在windows(VS2015)下的编译和安装
Python3.7源码在windows(VS2015)下的编译和安装 下载官方源码,使用vs2015(WIN10SDK),最python3.7.0的源码进行编译,编译出不同的版本(release,de ...
- CentOS 6.3下源码安装LAMP(Linux+Apache+Mysql+Php)环境【转载】
本文转载自 园友David_Tang的博客,如有侵权请联系本人及时删除,原文地址: http://www.cnblogs.com/mchina/archive/2012/11/28/2778779.h ...
- netcdf源码在windows上的编译
作者:朱金灿 来源:http://blog.csdn.net/clever101 今天搞搞netcdf源码在windows上的编译,折腾了半天,算是搞成了,特地记录一下过程.我的目标是要生成netcd ...
- Apache源码包在LINUX(CENTOS6.8)中的安装(出现问题及解决)
任务:在CENT6.8系统中安装Apache(版本为:httpd-2.4.41) 前提:由于源码包必须先编译后安装,所以必须先安装编译器:gcc 理论步骤: 1.检测gcc软件包,如果不存在则进行安装 ...
随机推荐
- C++面试八股文:什么是构造函数?
某日二师兄参加XXX科技公司的C++工程师开发岗位第29面: 面试官:什么是构造函数? 二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象.构造函数的名称与类的名称相同,并且没有返回类型. ...
- 了解前端中的BFC(块级格式化上下文)
BFC(块级格式化上下文) 什么是BFC 指的是一个块级渲染作用域,该区域内拥有一套完整的规则来约束块级盒子的布局,且与区域外部无关. 为什么要使用BFC 当一个盒子不设置高度,当其中的子元素都浮动时 ...
- Blazor资源大全,很棒的Blazor
Blazor资源大全 一个收集了很棒的Blazor资源的集合. Blazor是一个使用C#/Razor和HTML在浏览器中运行的.NET Web框架. 欢迎贡献!请先查看贡献指南.感谢所有的贡献者,你 ...
- Mysql高级1-存储引擎
一.Mysql体系结构 1.1.连接层 最上层是一个客户端和链接服务,主要完成一些类似于链接处理,授权认证,及相关的安全方案,服务器也会为安全接入的而每个客户端验证它所具有的操作权限 1.2.服务层 ...
- opencv-python中 boundingRect(cnt)以及cv2.rectangle用法
矩形边框(Bounding Rectangle)是说,用一个最小的矩形,把找到的形状包起来.还有一个带旋转的矩形,面积会更小,效果见下图 首先介绍下cv2.boundingRect(img)这个函数 ...
- 内网渗透大杀器fscan
fscan简介 一款内网综合扫描工具,方便一键自动化.全方位漏扫扫描.支持主机存活探测.端口扫描.常见服务的爆破.ms17010.redis批量写公钥.计划任务反弹shell.读取win网卡信息.we ...
- Unity的IFilterBuildAssemblies:深入解析与实用案例
Unity IFilterBuildAssemblies Unity IFilterBuildAssemblies是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目时自定义哪些程序集需要 ...
- pc 移动端 双端切换
实现一个项目匹配多个端,使用vue.config自带的page 实现多个页面切换.官网介绍:https://cli.vuejs.org/zh/config/#pages 在创建的vue项目中找到 vu ...
- SpringBoot3分库分表
标签:ShardingSphere5.分库.分表: 一.简介 分库分表的设计和实现方式,在之前的内容中总结过很多,本文基于SpringBoot3和ShardingSphere5框架实现数据分库分表的能 ...
- 【路由器】OpenWrt 简介和安装
目录 简介 来源 介绍 安装 一般安装流程 固件搜索下载 参考资料 简介 来源 2002 年底 Linksys 公司推出 WRT-54G,采用了 Linux 取代了原来的 vXworks 系统.迫于 ...