ESFramework Demo -- P2P通信Demo(附源码)

简介: 现在我们将在ESFramework Demo -- 文件传送Demo 的基础上,使用ESPlus提供的第四个武器,为其增加P2P通信的功能。在阅读本文之前,请务必先掌握ESFramework 开发手册(04) -- 可靠的P2P 一文中介绍的P2P的基础知识以及相关API的用法。

现在我们将在ESFramework Demo -- 文件传送Demo 的基础上,使用ESPlus提供的第四个武器,为其增加P2P通信的功能。在阅读本文之前,请务必先掌握ESFramework 开发手册(04) -- 可靠的P2P 一文中介绍的P2P的基础知识以及相关API的用法。

      本Demo主要演示以下功能:

(1)创建基于TCP的P2P通道

(2)创建基于UDP的P2P通道(内部使用可靠的UDP)

(3)使用P2P通道发送消息和传送文件 

一.服务端

      在P2P打洞的过程中,服务端会参与协助P2P通道的建立,整个过程是由ESFramework/ESPlus内部自动完成的,而这个过程对于框架使用者是透明的。P2P通道创建后,客户端与客户端之间的通信就与服务器没有任何关系了。所以我们直接把上一个demo的服务端拿过来用,不需要做任何修改。 

二.客户端

      客户端主要使用IRapidPassiveEngine提供的P2PController来查询和控制P2P通道的状态。

尝试创建P2P通道    

      正如ESFramework 开发手册(04) -- 可靠的P2P 一文中介绍的,并不是所有的客户端之间的P2P通道都可以创建成功,创建P2P通道是一个尝试的过程,IP2PController的P2PConnectAsyn方法就是尝试与目标用户创建P2P通道。

      时机很重要。在何时创建P2P通道了?一般而言,是在两个客户端需要高频通信之前,调用P2PConnectAsyn进行尝试创建。

      在本Demo中,我们是在每次打开与目标用户的聊天窗口的时候,来尝试创建P2P通道的。如下所示:

复制代码
  void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button != System.Windows.Forms.MouseButtons.Left)
{
return;
}

ListViewHitTestInfo info = this.listView1.HitTest(e.Location);
if (info.Item != null)
{
//尝试与目标用户建立P2P通道
this.rapidPassiveEngine.P2PController.P2PConnectAsyn(info.Item.Text);

ChatForm form = this.chatFormManager.GetForm(info.Item.Text);
           ......
       }
  }
复制代码

      使用P2PConnectAsyn方法开始打洞时,若双方位于同一局域网,一般会建立起基于TCP的P2P通道;若双方位于不同的网络,一般会建立起基于UDP的P2P的通道。如果与目标用户之间已经存在可用的P2P通道,则P2PConnectAsyn将不再做任何动作,而直接返回。

      为了获得P2P通道创建成功或失败以及后续P2P通道被关闭的通知,demo中我们在MainForm的Initialize方法中预定了P2PController的P2PChannelOpened和P2PChannelClosed事件。

   //预定P2P Channel创建成功的事件
this.rapidPassiveEngine.P2PController.P2PChannelOpened += new CbGeneric<P2PChannelState>(P2PController_P2PChannelOpened);
//预定P2P Channel关闭时的事件
this.rapidPassiveEngine.P2PController.P2PChannelClosed += new CbGeneric<P2PChannelState>(P2PController_P2PChannelClosed);

      当P2P通道创建成功或被关闭时,本demo通过修改对应聊天窗口的Title文字来显示这种状态。比如,当P2P通道创建成功时,聊天窗口的Title显示如下:

     

      通常,如果两个客户端位于同一个LAN,或者有一个客户端直接位于Internet上,则它们之间的P2P通道是基于TCP的;否则,创建的P2P通道是基于UDP的。

      ChatForm提供了ShowP2PChannelState方法来显示与聊天对象之间的P2P通道状态。

复制代码
       ///<summary>
/// 显示P2P连接的状态
///</summary>
public void ShowP2PChannelState(P2PChannelState state)
{
this.Text = (state != null) ? string.Format("正在与{0}对话中【{1}直连:{2}】...", this.friendID, state.ProtocolType, state.DestIPE) : string.Format("正在与{0}对话中...", this.friendID);
}
复制代码

      请注意,当与目标用户之间没有P2P通道时,P2PController的GetP2PChannelState方法返回的是null。

观察P2P通信

      当P2P通道创建成功后,两个用户之间的后续通信将经过P2P通道传送,在本Demo中,表示后续的聊天消息以及文件传送都将通过P2P通道进行。

      那么,如何判断消息是通过服务器中转的,还是经过P2P通道直接传送的了?我们常用的有两个简单的方法。

(1)观察服务器的MainServerForm界面。      

      

      如果消息是经过服务器中转的,那么界面上显示消息接收者用户对应的“下载次数”、“上传次数”、“最后一次下载时间”等都会跟着发生变化。就本例来说,每当你给对方发送一个聊天消息,如果是经过服务器中转,那么界面上显示的对方的下载次数会增加1,自己的上传次数也增加1,自己的最后一次上传时间也会变化。而如果消息是通过P2P通道传送的,这些数据就不会受影响。

(2)查看资源监视器

      如果是Win7的系统,任务管理器“性能”显示中提供了“资源监视器”,可以监控网络的活动。使用它,我们就可以看到应用程序在和哪些机器进行通信。如下图所示:

      

      上面是我们另一个P2P应用demo的截图,图中59.175.145.163是服务器的IP,而我们看到OMCS.ClientDemo.exe接收数据的主要流量来自于ZY-PC这台电脑,这表示两个客户端之间的数据是经过P2P通道传送的,没有通过服务器中转。之所以图中显示的客户端与服务器之间还有微小的流量,那是由类似定时心跳消息等产生的。

      如果不是Win7系统,也可以通过安装网络监控软件(如NetLimiter)来查看这些信息。

三.源码下载

 ESFramework.Demos.P2P 源码

  

阅读 更多ESFramework开发手册系列文章

----------------------------------------------------------------------------------------------------------------------------------------------- 

关于ESFramework的任何问题,欢迎联系我们:

电话:027-87638960

Q Q:372841921

相关文章
|
17天前
|
网络协议 安全 JavaScript
Web实时通信的学习之旅:WebSocket入门指南及示例演示
Web实时通信的学习之旅:WebSocket入门指南及示例演示
86 0
|
XML 缓存 编解码
Qt开发技术:QtSVG介绍、使用和Demo
Qt开发技术:QtSVG介绍、使用和Demo
Qt开发技术:QtSVG介绍、使用和Demo
|
开发框架 JavaScript 前端开发
如何使用SpringBoot和Netty实现一个WebSocket服务器,并配合Vue前端实现聊天功能?
如何使用SpringBoot和Netty实现一个WebSocket服务器,并配合Vue前端实现聊天功能?
302 0
|
Ubuntu IDE Java
Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo
在arm上做了Qt的应用程序,为了在局域网实现web页的访问方式来配置arm上Qt的程序,局域网轻量级http服务器是很好的实现方式之一,有机会做国产麒麟上Qt的http服务器,正好接触到了QtWebApp可以实现。   本篇实战解说QtWebApp的轻量级Demo。   本篇篇幅较长,为了保持基础的完整性将必要的东西都放在本篇。
❤️一个聊天室案例带你了解Node.js+ws模块是如何实现websocket通信的!
❤️一个聊天室案例带你了解Node.js+ws模块是如何实现websocket通信的!
221 0
❤️一个聊天室案例带你了解Node.js+ws模块是如何实现websocket通信的!
|
前端开发 Java
Webscoket通信,java使用springboot集成,实现页面无刷新消息提示
Webscoket通信,java使用springboot集成,实现页面无刷新消息提示
214 0
|
Java 程序员 网络安全
java版gRPC实战之六:客户端动态获取服务端地址
当服务端地址发生改变时,客户端不改配置不重启,就能感知到服务端的变化吗?
733 0
java版gRPC实战之六:客户端动态获取服务端地址
|
JavaScript 索引 容器
基于uniapp实现的交互视频demo
一个互动视频项目,播放段剧情后出现交互按钮,用户通过按钮交互,进入下一对应剧情
762 0
|
网络协议 监控 API
ESFramework Demo -- P2P通信Demo(附源码)
现在我们将在ESFramework Demo -- 文件传送Demo 的基础上,使用ESPlus提供的第四个武器,为其增加P2P通信的功能。在阅读本文之前,请务必先掌握ESFramework 开发手册(04) -- 可靠的P2P 一文中介绍的P2P的基础知识以及相关API的用法。
1140 0