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 源码下载中心 ,谢谢 。
GGTalk 开源即时通讯系统源码剖析之:远程磁盘 (低调赠送GGTalk最新源码)的更多相关文章
- GGTalk——C#开源即时通讯系统源码介绍系列(一)
坦白讲,我们公司其实没啥技术实力,之所以还能不断接到各种项目,全凭我们老板神通广大!要知道他每次的饭局上可都是些什么人物! 但是项目接下一大把,就凭咱哥儿几个的水平,想要独立自主.保质保量保期地一个个 ...
- 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】
像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用C#开源即时通讯系统——GGTalk的 ...
- GGTalk ——C#开源即时通讯系统
http://www.cnblogs.com/justnow/ GGTalk ——C#开源即时通讯系统 下载中心 GGTalk(简称GG)是可在广域网部署运行的QQ高仿版,2013.8.7发布GG ...
- 即时通信系统中实现聊天消息加密,让通信更安全【低调赠送:C#开源即时通讯系统(支持广域网)——GGTalk4.5 最新源码】
在即时通讯系统(IM)中,加密重要的通信消息,是一个常见的需求.尤其在一些政府部门的即时通信软件中(如税务系统),对即时聊天消息进行加密是非常重要的一个功能,因为谈话中可能会涉及到机密的数据.我在最新 ...
- 可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)
(最新版本:V6.2,2019.01.03 .Xamarin移动端版本已经推出,包括 Android 和 iOS) GGTalk开源即时通讯系统(简称GG)是QQ的高仿版,同时支持局域网和广域网, ...
- 【转】可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)
原文地址:http://www.cnblogs.com/justnow/p/3382160.html (最新版本:V6.0,2017.12.11 .即将推出Xamarin移动端版本,包括 Androi ...
- GGTalk即时通讯系统(支持广域网)终于有移动端了!(技术原理、实现、源码)
首先要感谢大家一直以来对于GGTalk即时通讯系统的关注和支持!GGTalk即时通讯系统的不断完善与大家的支持分不开! 从2013年最初的GG1.0开放源码以来,到后来陆续增加了网盘功能.远程协助功能 ...
- 【转】GGTalk即时通讯系统(支持广域网)终于有移动端了!(技术原理、实现、源码)
原文地址:http://www.cnblogs.com/justnow/p/4836636.html 首先要感谢大家一直以来对于GGTalk即时通讯系统的关注和支持!GGTalk即时通讯系统的不断完善 ...
- 新一代开源即时通讯应用源码定制 运营级IM聊天源码
公司介绍:我们是专业的IM服务提供商!哇呼Chat是一款包含android客户端/ios客户端/pc客户端/WEB客户端的即时通讯系统.本系统完全自主研发,服务器端源码直接部署在客户主机.非任何第三方 ...
- 视酷即时通讯系统应用源码 V1.0
视酷即时通讯系统(原创),成熟稳定,拥有和微信一样强大的功能不再是梦,节省几个月研发时间迅速融合进项目中: 1.首家支持聊天室群聊 2.支持和微信一样的语音聊天,可以显示时长.未读状态,自动轮播未读语 ...
随机推荐
- [tldr] 使用ip.sb检查自己所在局域网的公网IP
使用ip a等一些命令行工具可以帮助我们检查自己的内网IP,但是,如何获取自己的在公网下的IP(即当前所在的局域网被分配的公网IP) 如果使用爬虫,这个IP也是很重要的.BAN IP就是这个IP ht ...
- php7安装redis6扩展
1.下载 php-redis扩展下载地址: http://pecl.php.net/package/redis 具体下载版本以自己的PHP版本信息为准 linux下载命令 wget http://pe ...
- 【Linux】5.10 输入输出重定向
Shell 输入/输出重定向 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令 ...
- Python复制单个文件为多个脚本
编写背景: 由于线上用户反馈媒体添加页加载时间很长,猜测是由于本地视频/图片数量过多引起,于是编写此脚本以便快速生成大量测试视频 代码如下: # coding=utf-8 import os impo ...
- nohup启动jar包
1. 后台启动jar包,并追加日志到日志文件run.log nohup java -jar wash-1.0-SNAPSHOT.jar >> run.log 2>&1 &am ...
- Web前端入门第 37 问:多图细说 CSS grid 网格布局(二)子元素相关属性
学习本文之前,建议先学习上一篇了解父元素的相关属性. 前文对 grid 网格布局中父元素容器相关的 CSS 属性做了详细介绍,本篇将继续学习子元素相关的 CSS 属性. 网格布局的一大波样式属性,父元 ...
- 17.1K star!两小时就能训练出专属于自己的个性化小模型,这个开源项目让AI触手可及!
「只需一张消费级显卡,2小时完成26M参数GPT训练!」「从零构建中文大模型的最佳实践指南」「兼容OpenAI API,轻松接入各类AI应用平台」 项目介绍 MiniMind是由开发者Jingyao ...
- 解决【Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modul】报错问题
参考: https://blog.csdn.net/weixin_36146275/article/details/77447659
- 【经验】Git仓库多账号管理与部署|SSH密钥设置
生成 SSH 密钥 先打开一个git窗口,生成ssh密钥. 如果打开的不是git窗口,而是cmd窗口,则需要先切换到C:\Users\用户名\.ssh目录下. 下面这条指令的your_email和yo ...
- deepseek+coze实战:一键抓取百条抖音爆款视频,自动存入飞书表格
大家好,我是汤师爷~ 批量获取抖音视频文案这件事,一直有技术门槛. 很多朋友因为不懂技术,只能花钱买工具来完成这项任务. 今天我要分享一个Coze智能体的解决方案 只需输入关键词就能自动批量获取视频文 ...