GGTalk 开源即时通讯系统源码剖析之:远程磁盘 (低调赠送GGTalk最新源码)

继上篇《GGTalk 开源即时通讯系统源码剖析之:聊天消息防错漏机制》介绍了 GGTalk 对消息的可靠性,即消息的不丢失和不重复做了一系列优化处理,以保证不会错漏消息。这篇我们来剖析 GGTalk 新增的远程磁盘功能其对应的源码实现。

在之前的博文《实现远程磁盘:像访问自己的电脑硬盘一样访问对方的电脑硬盘 》,我们通过一个Demo介绍了访问远程磁盘如何实现。最近,我们已经在GGTalk开源即时通讯IM的最新版中增加访问好友磁盘的功能:在一对一的对话窗口,请求方可以发起访问对方磁盘的请求,如果对方同意,则请求方就可以通过远程磁盘的窗口来操作对方的磁盘了。现在我们来看看GGTalk的远程磁盘这一功能具体是如何实现的,大家可以先下载GGTalk的最新源码,然后对照源码,更容易理解本文的内容。

一. 定义消息协议

在远程磁盘请求方和应答方相互通信之前,我们先定义好远程磁盘这一功能需要用到的消息协议。

复制代码
/// <summary>
/// 交互媒体的类型。
/// </summary>
public enum CommunicateMediaType
{
    Video = 0,
    Audio,
    RemoteHelp,
    RemoteControl,
    RemoteDisk,
    GroupVideo
}

在交互媒体的类型枚举上,我们增加了 远程磁盘(RemoteDisk)这个类型。

再结合原先的 CommunicateType 枚举,我们就可以组合出远程磁盘相关的业务通信:请求、应答(同意或拒绝)、中断等。

复制代码
/// <summary>
/// 交互的类型。比如 请求视频会话,同意视频会话,拒绝视频会话,终止视频会话
/// </summary>
public enum CommunicateType
{
    Request = 0,
    Agree,
    Reject,
    Terminate,
    Busy
}

有了上面的铺垫,我们就可以来实现整个远程磁盘功能的业务流程了。

二. 远程磁盘请求方实现

首先,使用VS 2022 打开 GGTalk 解决方案,找到GGTalk 客户端项目(Windows版):

  我们在一对一的聊天窗口 FriendChatForm (在Forms文件夹下)上增加"请求访问对方磁盘"的按钮,如下图所示:

点击该按钮时,将执行如下动作:

复制代码
public void RequestControlFriendDisk()
{
    //如果自己掉线,则直接返回。
    if (this.resourceCenter.ClientGlobalCache.CurrentUser.UserStatus == UserStatus.OffLine)
    {
        return;
    }           

    this.resourceCenter.ClientOutter.SendMediaCommunicate(this.currentFriend.ID, CommunicateMediaType.RemoteDisk, CommunicateType.Request, null);
    NDiskOutter diskOutter = new NDiskOutter(this.resourceCenter.RapidPassiveEngine, this.resourceCenter.NDiskPassiveHandler);            
    this.remoteDiskForm = new RemoteDiskForm(this.currentFriend.ID,ClientType.DotNET,this.currentFriend.DisplayName, diskOutter, this.resourceCenter.RapidPassiveEngine.FileOutter, this.resourceCenter.CurrentUserID);
    this.remoteDiskForm.RemoteDiskRequestCancelled += new CbGeneric(remoteDiskForm_RemoteDiskRequestCancelled);
    this.remoteDiskForm.RemoteDiskEnded += new CbGeneric<bool>(remoteDiskForm_RemoteDiskEnded);
    this.remoteDiskForm.Show();
}

(1)客户端通过调用 IClientOutter 的 SendMediaCommunicate 方法,来实现与远程磁盘功能相关的业务通信。

(2)通过 CommunicateMediaType.RemoteDisk 和 CommunicateType.Request 来表名这次交互发送的是一个远程磁盘请求。

(3)在等待对方应答期间,使用 RemoteDiskForm 来显示正在等待对方回复。如下图所示:

(4)如果对方同意了远程磁盘请求,那么RemoteDiskForm 将改变状态,请求方就能通过该窗体来操作对方的磁盘,如下图所示:

关于 RemoteDiskForm 的具体实现细节,可以参考 《实现远程磁盘:像访问自己的电脑硬盘一样访问对方的电脑硬盘 》。

三. 远程磁盘应答方实现

  当应答方收到跟远程磁盘相关的业务消息时,会进入到 RemoteDiskManager的 HandleRemoteDisk 方法,如下代码所示:

复制代码
public void HandleRemoteDisk(CommunicateType communicateType, string tag)
{
    if (communicateType == CommunicateType.Request)
    {
        this.OnRemoteDiskRequestReceived();
        this.ownerForm.FlashWindow();
        return;
    }

    if (communicateType == CommunicateType.Agree)
    {
        this.OnRemoteDiskAnswerReceived(true);
        this.ownerForm.FlashWindow();
        return;
    }

    if (communicateType == CommunicateType.Reject)
    {
        this.OnRemoteDiskAnswerReceived(false);
        this.ownerForm.FlashWindow();
        return;
    }

    if (communicateType == CommunicateType.Terminate)
    {
        if (tag == "owner")
        {
            this.OnOwnerTerminateRemoteDisk();
        }
        else
        {
            this.OnGuestCloseRemoteDisk();
        }
        this.ownerForm.FlashWindow();
        return;
    }    
}

(1)在 OnRemoteDiskRequestReceived 方法中,会在窗体的右侧,显示远程磁盘请求,如下截图:

(2)当应答方点击"接受"或"拒绝"按钮时,也将通过调用 IClientOutter 的 SendMediaCommunicate 方法(位于RemoteDiskManager类),来将回复消息发送给请求方。

复制代码
void remoteDiskRequestPanel_RemoteRequestAnswerd(bool agree)
{
    this.ownerForm.RemoveDisplayedPanel(this.Title_Disk);    
    this.resourceCenter.ClientOutter.SendMediaCommunicate(this.currentFriend.ID, CommunicateMediaType.RemoteDisk, agree ? CommunicateType.Agree : CommunicateType.Reject, null);
    string showText = string.Format("您{0}了对方的磁盘访问请求。", agree ? "同意" : "拒绝");
    this.ownerForm.AppendSysMessage(showText);

    if (agree)
    {
        this.remoteDiskHandlePanel.OnAgree();
        this.ownerForm.AddDisplayedPanel(this.Title_Disk, this.remoteDiskHandlePanel);
    }
}

(3)如果点击"接受"按钮,则聊天窗体右侧将会出现"远程磁盘的控制面板",以随时可以收回远程磁盘控制权。

(4)在对方控制自己磁盘的过程中,应答方点击上方的"终止"按钮,即可结束控制。这是给对方发送一个"终止控制"的 CommunicateType.Terminate 消息:

复制代码
void remoteDiskHandlePanel_RemoteDiskTerminated()
{
    this.ownerForm.RemoveDisplayedPanel(this.Title_Disk);
    this.resourceCenter.ClientOutter.SendMediaCommunicate(this.currentFriend.ID, CommunicateMediaType.RemoteDisk, CommunicateType.Terminate, "owner");
    string showText = "您关闭了磁盘共享。";
    this.ownerForm.AppendSysMessage(showText);
}

四. 结语

以上就是关于 GGTalk 远程磁盘功能的设计与实现的核心了。在某些办公场景中,远程磁盘这个功能还是很有用的,所以,GGTalk 即时通讯就实现该功能,方便那些有需要的人。

如果你觉得还不错,请点赞支持啊!下篇再见!

若需下载GGTalk最新源码,请移不到 GGTalk 源码下载中心 ,谢谢 。

相关推荐
liana87446 天前
把核心数据锁进“信息孤岛”:专网独立部署如何实现安全与效率兼得
安全·数据安全·即时通讯·专网独立部署·信息孤岛·物理隔离
liana87447 天前
一体化安全协同:从协作工具到企业数字化中枢的演进
即时通讯·一体化安全协同·企业数字化底座·统一消息流·安全管控
玫幽倩7 天前
2026盘古石取证决赛(手机取证)
python·电子取证·计算机取证·聊天软件·手机取证·fic
liana874411 天前
企业IM即时通讯:从消息中枢到AI协作引擎的演进之路
私有化部署·即时通讯·企业im·ai协作引擎·ai融合
SoStraw1 个月前
基于P2P开发一个聊天桌面软件
p2p·quic·文件共享·打洞·通信·文件传输·聊天软件
jeff聊企业数字化1 个月前
私有化即时通讯选型指南:兼顾安全与高效
go·业界资讯·即时通讯
恒拓高科WorkPlus1 个月前
BeeWorks 私有化安全协作平台白皮书(2026 版)
即时通讯·白皮书·协作平台·协作平台白皮书·即时通讯白皮书
恒拓高科WorkPlus2 个月前
团队协作和即时通讯一体化的软件,目前哪个用户体验最好?
即时通讯·私有化的企业 im·企业 im
恒拓高科WorkPlus2 个月前
信创即时通讯怎么选?BeeWorks 的全栈适配与安全实践
即时通讯·信创即时通讯
恒拓高科WorkPlus2 个月前
私有化视频会议怎么选?BeeWorks Meet 的安全与高效之道
私有化部署·即时通讯·视频会议