Avalonia 实现简单的IM即时通讯、视频通话(源码,支持国产系统,统信、银河麒麟)

本文介绍了如何使用Avalonia框架在银河麒麟、统信UOS等国产操作系统上开发一个具备文字聊天、语音视频通话功能的跨平台IM应用,包括基本功能实现、开发环境配置和关键代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       Avalonia 在跨平台上的表现非常出色,对信创国产操作系统(像银河麒麟、统信UOS、Deepin等)也很不错。现在,我们就来使用 Avalonia 实现一个跨平台的简单IM,除了文字聊天外,还可以语音视频通话。废话不多说,我们开始吧!

      下图是这个简单IM的Avalonia客户端在国产统信UOS上的运行的截图:

一. IM 即时通讯系统主要功能

      这个简单的IM系统实现了以下功能:

1.基础功能、文字聊天

(1)客户端用户上下线时,通知其他在线用户。

(2)当客户端与服务端网络断开时,进行自动重连,当网络恢复后,重连成功。

(3)所有在线用户之间可以进行文字聊天(支持表情,支持撤回消息、删除消息)。

(4)文件传送。

2.语音视频聊天、远程桌面

(1)一方发起视频对话请求,对方同意后,即可开始视频对话。

(2)在对话的过程中,任何一方都可以挂断,以终止对话。

(3)在对话的过程中,任何一方掉线,都会自动终止对话。

(4)双击视频窗口,会全屏显示视频,按esc退出全屏。

(5)远程桌面或远程协助功能,也是跟视频聊天同样的流程,不再赘述。

二.开发环境

1.开发工具:

Visual Studio 2022

2. 开发框架:

.NET Core 3.1

3.开发语言:

C#

4.其它框架:

Avalonia UI 框架(版本:0.10.22)、ESFramework 通信框架 (版本:7.2)

注:建议 Avalonia 使用0.10.*的版本,精简而且很稳定,而最新的11.0的版本太庞大了。

三.具体实现

下面我们讲一下Demo中核心的代码实现,大家从文末下载源码并对照着源码看,会更清楚些。

1.自定义消息类型 InformationTypes

       若要实现上述功能列表中列出来的所有功能,我们先要定义相应的通信消息的消息类型,如下所示:

    public static class InformationTypes
    {
        /// <summary>
        /// 文字(表情)聊天信息
        /// </summary>
        public const int TextChat = 0;

        /// <summary>
        /// 文字(表情)聊天信息 (由服务端转发给消息接收方)
        /// </summary>
        public const int TextChat4Transit = 1;

        /// <summary>
        /// 图片聊天信息
        /// </summary>
        public const int ImageChat = 2;

        /// <summary>
        /// 收到消息发送者 撤回消息请求
        /// </summary>
        public const int RecallMsg = 3;

        /// <summary>
        /// 客户端异步调用服务端
        /// </summary>
        public const int ClientSyncCallServer = 4;

        /// <summary>
        /// 视频请求 5
        /// </summary>
        public const int VideoRequest = 5;

        /// <summary>
        /// 回复视频请求的结果 6
        /// </summary>
        public const int VideoResult = 6;

        /// <summary>
        /// 通知对方 挂断 视频连接 7
        /// </summary>
        public const int CloseVideo = 7;

        /// <summary>
        /// 通知好友 网络原因,导致 视频中断 8
        /// </summary>
        public const int NetReasonCloseVideo = 8;

        /// <summary>
        /// 通知对方(忙线中) 挂断 视频连接 9
        /// </summary>
        public const int BusyLine = 9;

        /// <summary>
        /// 收到远程协助请求
        /// </summary>
        public const int AssistReceive = 10;

        /// <summary>
        /// 协助方拒绝远程协助
        /// </summary>
        public const int AssistGusetReject = 11;

        /// <summary>
        /// 协助方同意远程协助
        /// </summary>
        public const int AssistGusetAgree = 12;

        /// <summary>
        /// 请求方关闭远程协助
        /// </summary>
        public const int AssistOwnerClose = 13;

        /// <summary>
        /// 协助方关闭远程协助
        /// </summary>
        public const int AssistGusetClose = 14;
    }

      在约定好消息类型之后,我们就可以实现业务逻辑功能了。 

2.定义协议类

      信息类型定义好后,我们接下来定义信息协议。

      对于聊天消息(InformationTypes.EmotionTextChat),专门定义了一个协议类:ChatMessageRecord。

    public class ChatMessageRecord
    {
        public string Guid { get; set; }

        public DateTime MessageTime { get; set; }

        public string SpeakerID { get; set; }

        public string ListenerID { get; set; }

        public ChatMessageType ChatMessageType { get; set; }

        public string ContentStr { get; set; }

        public byte[] ImgData { get; set; }

        public string FilePath { get; set; }
    }

 对于同步调用(InformationTypes.ClientSyncCallServer),我们示例的是向服务器请求加法运算的结果,协议类用的是MathModel。

3.实现自定义信息处理器

      客户端的MainForm实现了ICustomizeHandler接口,其主要实现HandleInformation方法,来处理收到的聊天信息和振动提醒。

  void HandleInformation(string sourceUserID, int informationType, byte[] info);

      服务端的CustomizeHandler实现了服务端的ICustomizeHandler接口,其主要实现HandleQuery方法来处理来自客户端的同步调用(InformationTypes.ClientCallServer)。

    byte[] HandleQuery(string sourceUserID, int informationType, byte[] info);

4.服务端验证用户登录的帐号

       服务端的BasicHandler类实现IBasicHandler接口,以验证登录用户的账号密码。

    public class BasicHandler : IBasicHandler
    { 
        /// <summary>
        /// 此处验证用户的账号和密码。返回true表示通过验证。
        /// </summary>  
        public bool VerifyUser(ClientType clientType, string systemToken, string userID, string password, out string failureCause)
        {
            failureCause = "";
            return true;
        }

        public string HandleQueryBeforeLogin(AgileIPE clientAddr, int queryType, string query)
        {
            return "";
        }
    }

       本demo中,假设所有的验证都通过,所以验证方法直接返回true。

5.客户端实现文字聊天功能

     通过IRapidPassiveEngine的 CustomizeOutter 的 Send 方法来发送文字表情聊天消息。 

     在发送文字聊天消息时,有两个发送按钮,“发送1”和“发送2”,分别演示了两种发送消息给对方的方式:

(1)直接发给对方。(若P2P通道存在,则经由P2P通道发送)

        internal static void SendTextMsgToClient(ChatMessageRecord record)
        {
            try
            {
                string cont = JsonConvert.SerializeObject(record);
                byte[] recordInfo = Encoding.UTF8.GetBytes(cont);
                //使用Tag携带 接收者的ID
                App.PassiveEngine.CustomizeOutter.Send(record.ListenerID, InformationTypes.TextChat4Transit, recordInfo);
            }
            catch (Exception e)
            {
                logger.Log(e, "GlobalHelper.SendTextMsgToClient", ErrorLevel.Standard);
            }
        }

 聊天消息 ChatMessageRecord 对象先由JSON序列化成字符串,然后在使用UTF-8转成字节数组,然后通过通信引擎的CustomizeOutter发送出去。

(2)先发给服务器,再由服务器转发给对方。     

      具体实现,大家去参看源码,这里就不再赘述了。

6.客户端实现语音视频通话功能

         语音视频通话实际运行起来后的效果如下所示:

         我们先简单描述一下实现视频对话流程的要点,更详细的细节请查阅源代码。

(1)发起方发送InformationTypes.VideoRequest类型的信息给对方,以请求视频对话。

     程序中是在 VideoChatWindow 窗口显示的时候,来做这件事的:

        protected override void OnInitialized()
        {
            base.OnInitialized(); 
            this.SetWindowStats();
            if (!this.IsWorking)
            {
                VideoController.Singleton.SendMessage(this.DestID, InformationTypes.VideoRequest, null);
                CommonHelper.AddSystemMsg(this.DestID, "向对方发起视频通话邀请");
            }
        }

(2)接收方收到请求后,界面提示用户是同意还是拒绝,用户选择后,将发送InformationTypes.VideoResult类型的信息给请求方,信息的内容是一个bool值,true表示同意,false表示拒绝。

(3)发起方收到回复,如果回复为拒绝,则界面给出对应的提示;如果回复为同意,则进入(4)。

(4)先说接收方,如果同意视频,则发送回复后,立即调用DynamicCameraConnector和MicrophoneConnector的Connect方法,连接到对方的摄像头、麦克风。

        internal void BeginConnect()
        {
            UiSafeInvoker.ActionOnUI(() =>
            {
                string tip = this.IsWorking ? "已同意对方的视频通话" : "对方同意了你的视频通话请求";
                CommonHelper.AddSystemMsg(this.DestID, tip);
                this.IsWorking = true;
                this.NotifyOther = 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);
            });
        }

(5)对于发起方,当收到对方同意的回复后,也立即调用DynamicCameraConnector和MicrophoneConnector的Connect方法,连接到接收方的摄像头、麦克风。

(6)当一方点击挂断的按钮时,就会发送InformationTypes.CloseVideo类型的信息给对方,并调用DynamicCameraConnector和MicrophoneConnector的Disconnect方法断开到对方设备的连接。

(7)另一方接收到InformationTypes.CloseVideo类型的信息时,也会调用DynamicCameraConnector和MicrophoneConnector的Disconnect方法以断开连接。

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            this.otherCamera?.Disconnect();
            this.otherCamera?.Dispose();

            this.microphoneConnector?.Disconnect();
            this.microphoneConnector?.Dispose();

            this.selfCamera?.Disconnect();
            this.selfCamera?.Dispose();
        }

8)如果接收到自己掉线的事件或好友掉线的事件,也采用类似挂断对话的处理。 

四.下载

    Avalonia 版本即时通讯源码: IM_VideoChat.Avalonia.rar

该源码中包括如下项目:

(1)Oraycn.Demos.VideoChat.LinuxServer :     该Demo的Linux服务端(基于.NetCore)。

(2)Oraycn.Demos.VideoChat.ClientAvalonia :   该Demo的 Avalonia 客户端。

          注: Linux客户端内置的是x86/x64非托管so库,若需要其它架构的so,请留言免费获取。  

企业即时通讯系统源代码销售 类似 MSN、QQ、雅虎通的即时通讯工具,是一套一通讯、商务协作的即时通讯工具。主要应用于企业内部沟 通、各种会议,企业和客户以及合作 伙伴的交流,客户服务系统,远程培训教育系统,证券业的股评、咨询 系统,医疗的远程会诊系统, 以及其他很多行业的通过网络进行的实时音视频交流的系统。 1 状态管理 维护所有在线人员的状态,除了系统提供的几个常用的状态(如:离开、忙碌、参加会议等)之外,系统同时提 供了自定义在线状态的功能,以满足各种应用场合的需求. 2 即时消息 在 NetMessenger 上发消息完全可以和手头的其他工作同时进行。比 Email 要快速,无需等待;比电话交流 方式要丰富,不用消耗时间在拨电话、等待对方接听、或者对方不在时要多次重拨等,可以省去许多长途电话 费,办公室电话铃声和在电话上讲话的干扰也大幅度降低;在电话上不容易讲清楚的如一串数字、地址等可以 很方便的用文字来描述,可以直接把一幅图或者文件发给对方;可以打开语音、视频进行对话 3 语音对话 采用成熟语音技术,通话双方即使是使用拨号上网也可得到很好的通话效果. 4 网络摄像机 允许查看联机对话用户的摄像头. 5 文件传输 系统提供了高速、稳定的实时文件传输功能,支持断点续传. 6 组织机构管理 包括部门、用户,职位以及级别管理(新增,删除,修改). 7 息传输可靠、安全 密码和消息内容都采用加密技术. 9 栩栩如生的聊天场景 可以身临其境地聊天,动人的聊天场景,迷人的场景动作,浪漫其实很简单! 10 灵巧的捕捉屏幕功能 截取自己的屏幕给对方看. 11 自定义页面 NetMessenger中有三个地方,您可以自定义页面,方便您在NetMessenger 中提供您自己的息. 12 群发消息给员工 可以发送消息给想发送消息的员工. 13 群发消息给部门 可以发送消息给选中的部门,部门的员工会自动收到发送的消息. 14 邀请 可以邀请需要的人一起聊天. 15 上线,离线提示 可以不需要看自己的NetMessenger,系统会提示谁上线了,谁下线了. 16 自定义字体 可以自定义自己需要的字体,字形,大小,颜色,有无下划线等. 17 自动快捷输入表情符 可以方便迅速地输入您想要的表情,好心情,坏心情,只要轻轻点一点. 18 自定义NetMessenger风格 可以自定义自己需要的风格. 19 组织架构 登录后即可清晰看到由树型目录表达的多层次企业组织架构实时更新息,在 NetMessenger 上查看对方资料 息 一目了然的树型组织架构 ,可让每个员工迅速地融入到企业当中,即使在彼此还不认识的情况下也可以很好 的协作。 20 消息提示 系统会自动提示消息来了. 21 聊天记录 它可以记录所有的聊天记录方便查看. 22 留言功能 如果对方不在线了,可以留言给对方,对方只要一上线就可以及时的收到留言. 23 系统的自动检测 如果长时间没有动鼠标了.系统会自动离开. 24 聊天记录保密 聊天记录使用了DES加密算法,安全性绝对可靠. 25 隐身功能 如果不想别人知道你在线上,用户可以使用隐身的功能.(选择“显示为脱机”状态,您可以接收息,但别人 看不到你在线) 现对外公开低价出售P2P即时通讯源码,无加密,组件齐全,调试非常简单方便! 发送联机或脱机消息,同时可自定义消息字体、颜色、大小等息,支持插入表情符号,屏幕截取。支持多人 消息群发等功能; 在线即时语音、视频聊天; 穿透网关防火墙,不同局域网任意对话; 系统采用先进的点对点通讯技术,消息(包括文本、语音、视频、文件)的传输大多数情况不需要经服务器中 转而直接发往接收者所使用的机器,传输速度更快。而且因服务器仅仅只是起着维护用户状态列表的功能,因 此占用资源极少,可允许同时在线的人数就越多,对系统的影响也最小。 可以设置各种离线状态,支持自定义状态; 用户可自定义界面,界面皮肤可在线更新; 灵活支持Oracle、Sql Server等数据库; 服务器端资源占用低,通讯中不占用服务端资源; 联系QQ:571033003 全套源码 技术指导 编译通过= 5000 元 应用领域 即时通讯软件主要应用于企业内部沟通、各种会议,企业和客户间合作交流,客户服务系统,远程培训教 育系统,证券业的股评、咨询系统,医疗的远程会诊系统,各种购物网站, 物流系统等! 测试服务器请与QQ:571033003联系商祺!
### 在银河麒麟服务器版上运行 Avalonia 应用的解决方案 要在银河麒麟服务器版操作系统上运行 Avalonia 庢应用,需要确保以下几点:环境配置正确、依赖项完整以及应用程序兼容性。以下是具体实现方式: #### 1. 确保系统支持 .NET Core 或 .NET 6+ Avalonia 是基于 .NET Core 的跨平台 UI 框架,因此需要在银河麒麟服务器版上安装 .NET Core 或更高版本的 .NET SDK 和运行时。可以通过以下命令安装 .NET SDK: ```bash wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh sudo chmod +x ./dotnet-install.sh ./dotnet-install.sh --channel 6.0 --install-dir /usr/share/dotnet --version latest ``` 安装完成后,验证是否成功安装: ```bash dotnet --version ``` 如果输出为 `6.x` 或更高版本,则说明安装成功[^1]。 #### 2. 安装 Avalonia 所需的依赖库 Avalonia 在 Linux 平台上运行时,可能需要一些额外的依赖库,例如 GTK 或其他图形界面相关库。可以在银河麒麟服务器版上通过 APT 包管理器安装这些依赖项: ```bash sudo apt update sudo apt install -y libgtk-3-dev libx11-dev libxkbcommon-dev libgl1-mesa-dev ``` 上述命令会安装 GTK 开发库、X11 支持库以及其他必要的图形库,以确保 Avalonia 应用能够正常渲染和运行[^3]。 #### 3. 编译和运行 Avalonia 应用 将 Avalonia 项目代码克隆到本地,并使用以下命令进行编译和运行: ```bash # 克隆 Avalonia 示例项目(假设从 GitHub 获取) git clone https://github.com/AvaloniaUI/AvaloniaSample.git cd AvaloniaSample # 恢复 NuGet 包 dotnet restore # 构建项目 dotnet build # 运行项目 dotnet run ``` 如果一切配置正确,Avalonia 应用应该能够成功启动并显示界面。 #### 4. 处理可能的问题 - 如果遇到图形界面无法渲染的问题,请检查是否已正确安装图形库依赖。 - 如果出现 `.NET Core` 相关错误,请确保已正确安装 .NET SDK,并且版本满足 Avalonia 的最低要求。 - 如果需要离线安装 .NET SDK,可以参考银河麒麟桌面操作系统的本地源搭建方法[^2],将所需包下载到本地后手动安装。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值