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,可留下邮箱获取。

相关推荐
Splashtop高性能远程控制软件41 分钟前
centos远程桌面连接windows
linux·windows·centos·远程控制·远程桌面
Splashtop高性能远程控制软件6 天前
远程桌面内网穿透是什么?有什么作用?
内网穿透·远程控制·远程桌面·内网
Deng_Xian_Sheng10 天前
[Deepin] 简单使用 RustDesk 实现远程访问Deepin
frp·内网穿透·远程桌面·deepin·rustdesk
Splashtop高性能远程控制软件11 天前
Splasthop 安全远程访问帮助企业对抗 Cobalt Strike 载荷网络攻击
网络·安全·网络安全·远程控制·远程桌面
Splashtop高性能远程控制软件21 天前
什么软件可以用平板远程控制电脑?
电脑·远程控制·远程桌面
假装我不帅1 个月前
vscode开发avalonia
ide·vscode·编辑器·avalonia
极客先躯2 个月前
SSH客户端客户端工具都有哪些?
运维·自动化·ssh·远程桌面·命令行工具·ssh客户端
lishuangquan19872 个月前
AvaloniaUI的学习
ui·avalonia
Setli2 个月前
.NET跨平台UI框架Avalonia 11.1重磅发布
.net·跨平台·avalonia