.NET + Avalonia 实现视频聊天、远程桌面

2023-10-27 15:06:42 浏览数 (3)

前言

现在最火的.NET跨平台UI框架莫过于Avalonia了。

Avalonia 基于.NET Core,因此它可以运行在任何支持.NET Core的平台上。

之前基于CPF跨平台UI框架写过一个视频聊天的demo,而现在看来Avalonia是大势所趋,于是,我再写一个Avalonia版本的Demo来供大家参考,它可以在Windows和Linux(包括国产OS,如银河麒麟、统信UOS)上运行。

下图是视频聊天Demo的Avalonia客户端在国产统信UOS上的运行的截图:

一、功能介绍

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

1、视频聊天

每个登录的用户都可向其他任意在线用户发送视频聊天请求。

当收到来自其他在线用户的视频聊天邀请时,可接受或拒绝对方的请求。

当接受其他在线用户的视频聊天邀请时,即可开启视频聊天。

2、远程桌面

每个登录的用户都可向其他任意在线用户发送远程桌面请求;当对方未响应时,可主动取消远程桌面请求。

当收到来自其他在线用户请求控制桌面时,可接受或拒绝对方的请求。

当发送方收到其他在线用户同意控制其电脑时,即可开启远程桌面连接。

被控端和主控端都可主动断开远程桌面连接。

二、开发环境

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

代码语言:javascript复制
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、当发起视频聊天时,将显示视频聊天窗口

代码语言:javascript复制
/// <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、连接自己的摄像头

代码语言:javascript复制
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、发送视频通话请求

代码语言:javascript复制
protected override void OnInitialized()
   {
       base.OnInitialized(); 
       this.SetWindowStats();
       if (!this.IsWorking)
       {
           //向对方发起视频通话邀请
           VideoController.Singleton.SendMessage(this.DestID, InformationTypes.VideoRequest, null);
       }
   }
}
3、回复对方视频请求

1、当收到对方的视频聊天邀请时,将显示视频邀请窗口

2、发送回复视频聊天请求消息

代码语言:javascript复制
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、收到对方视频请求的回复

代码语言:javascript复制
/// <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;
    }
}

当对方回复同意时,将连接到对方的麦克风和摄像头,开始视频聊天会话:

代码语言:javascript复制
/// <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、当同意对方的控制请求时,对方就可以控制请求方的电脑了。

四、源码下载

1、.NET Core服务端 Avalonia客户端

https://www.oraycn.com/DownLoadFiles/OMCS/VideoChatMini.Avalonia.rar

在Windows上部署运行服务端和客户端很容易,大家也都很熟悉了。下面讲一下如何在Linux上部署运行这个视频聊天程序的服务端和客户端。

2、在Linux上部署运行说明

在部署之前,需要在linux服务端和客户端上分别安装 .Net core 3.1版本,命令行安装命令如下:

代码语言:javascript复制
yum install dotnet-sdk-3.1

检查版本安装情况

代码语言:javascript复制
dotnet --version

运行

1、在CentOS上启动VideoChatMini.ServerNetcore服务端

拷贝Oraycn.VideoChatMini.ServerNetcore项目下的Debug文件夹,到CentOS操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动服务端

代码语言:javascript复制
dotnet Oraycn.VideoChatMini.ServerNetcore.dll

2、在麒麟或统信UOS、Ubuntu上运行VideoChatMini.ClientAvalonia客户端

拷贝Oraycn.VideoChatMini.ClientAvalonia项目下的Debug文件夹,到麒麟或统信UOS、Ubuntu操作系统上,打开Debug -> netcoreapp3.1目录 ,在目录下打开终端,执行以下命令启动客户端

代码语言:javascript复制
dotnet Oraycn.VideoChatMini.ClientAvalonia.dll

命令执行成功后,就会出现之前截图的客户端主界面。

总结

Avalonia 支持在X64和ARM64架构的Linux上运行,Demo的运行目录下放的是X64架构的so,如果需要ARM64架构的so,可留下邮箱获取。

1 人点赞