原文网址: http://www.cnblogs.com/csdev

Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是:Apache License v2

开源地址是:https://github.com/MarcFletcher/NetworkComms.Net

我们知道TCP连接建立之后,如果没有心跳检测,连接一会就断开了。NetworkComms框架本身已经完美实现了心跳检测,我们在使用的时候不用再关心这个问题。

NetworkComms通信框架中服务器端设定的发送心跳消息的时间小于客户端发送心跳消息,所以发送心跳消息的工作主要由服务器端来完成。

如果服务器端超出常规时间没有发送心跳消息,客户端才会开始发送。

相关实现代码:

ConnectionStatic方法中:

  protected static void TriggerConnectionKeepAliveThread()
        {
            lock (staticConnectionLocker)
            {
#if NETFX_CORE
                if (!shutdownWorkerThreads && (connectionKeepAliveWorker == null || connectionKeepAliveWorker.IsCompleted))
                {
                    connectionKeepAliveWorker = new Task(ConnectionKeepAliveWorker, TaskCreationOptions.LongRunning);
                    connectionKeepAliveWorker.Start();
                }
#else
                if (!shutdownWorkerThreads && (connectionKeepAliveWorker == null || connectionKeepAliveWorker.ThreadState == ThreadState.Stopped))
                {
                    connectionKeepAliveWorker = new Thread(ConnectionKeepAliveWorker);
                    connectionKeepAliveWorker.Name = "ConnectionKeepAliveWorker";
                    connectionKeepAliveWorker.IsBackground = true;
                    connectionKeepAliveWorker.Start();
                }
#endif
            }
        }
 private static void ConnectionKeepAliveWorker()
        {
            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Debug("Connection keep alive polling thread has started.");
            DateTime lastPollCheck = DateTime.Now;

            while (!shutdownWorkerThreads)
            {
                try
                {
#if NET2
                    //We have a short sleep here so that we can exit the thread fairly quickly if we need too
                    if (ConnectionKeepAlivePollIntervalSecs == int.MaxValue)
                        workedThreadSignal.WaitOne(, false);
                    else
                        workedThreadSignal.WaitOne(, false);
#else
                    //We have a short sleep here so that we can exit the thread fairly quickly if we need too
                    if (ConnectionKeepAlivePollIntervalSecs == int.MaxValue)
                        workedThreadSignal.WaitOne();
                    else
                        workedThreadSignal.WaitOne();
#endif

                    //Check for shutdown here
                    if (shutdownWorkerThreads) break;

                    //Any connections which we have not seen in the last poll interval get tested using a null packet
                    if (ConnectionKeepAlivePollIntervalSecs < int.MaxValue && (DateTime.Now - lastPollCheck).TotalSeconds > (double)ConnectionKeepAlivePollIntervalSecs)
                    {
                        AllConnectionsSendNullPacketKeepAlive();
                        lastPollCheck = DateTime.Now;
                    }
                }
                catch (Exception ex)
                {
                    LogTools.LogException(ex, "ConnectionKeepAlivePollError");
                }
            }
        }
  private static void AllConnectionsSendNullPacketKeepAlive(bool returnImmediately = false)
        {
            if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Starting AllConnectionsSendNullPacketKeepAlive");

            //Loop through all connections and test the alive state
            List<Connection> allConnections = NetworkComms.GetExistingConnection(ApplicationLayerProtocolStatus.Enabled);
            int remainingConnectionCount = allConnections.Count;

            QueueItemPriority nullSendPriority = QueueItemPriority.AboveNormal;

            ManualResetEvent allConnectionsComplete = new ManualResetEvent(false);
            ; i < allConnections.Count; i++)
            {
                //We don't send null packets to unconnected UDP connections
                UDPConnection asUDP = allConnections[i] as UDPConnection;
                if (asUDP != null && asUDP.ConnectionUDPOptions == UDPOptions.None)
                {
                    )
                        allConnectionsComplete.Set();

                    continue;
                }
                else
                {
                    int innerIndex = i;
                    NetworkComms.CommsThreadPool.EnqueueItem(nullSendPriority, new WaitCallback((obj) =>
                    {
                        try
                        {
                            //If the connection is server side we poll preferentially
                            if (allConnections[innerIndex] != null)
                            {
                                if (allConnections[innerIndex].ConnectionInfo.ServerSide)
                                {
                                    //We check the last incoming traffic time
                                    //In scenarios where the client is sending us lots of data there is no need to poll
                                    if ((DateTime.Now - allConnections[innerIndex].ConnectionInfo.LastTrafficTime).TotalSeconds > ConnectionKeepAlivePollIntervalSecs)
                                        allConnections[innerIndex].SendNullPacket();
                                }
                                else
                                {
                                    //If we are client side we wait up to an additional 3 seconds to do the poll
                                    //This means the server will probably beat us
                                    if ((DateTime.Now - allConnections[innerIndex].ConnectionInfo.LastTrafficTime).TotalSeconds > ConnectionKeepAlivePollIntervalSecs + 1.0 + (NetworkComms.randomGen.NextDouble() * 2.0))
                                        allConnections[innerIndex].SendNullPacket();
                                }
                            }
                        }
                        catch (Exception) { }
                        finally
                        {
                            )
                                allConnectionsComplete.Set();
                        }
                    }), null);
                }
            }

            //Max wait is 1 seconds per connection
            )
            {
#if NET2
                , false))
#else
                ))
#endif
                    //This timeout should not really happen so we are going to log an error if it does
                    //LogTools.LogException(new TimeoutException("Timeout after " + allConnections.Count.ToString() + " seconds waiting for null packet sends to finish. " + remainingConnectionCount.ToString() + " connection waits remain. This error indicates very high send load or a possible send deadlock."), "NullPacketKeepAliveTimeoutError");
                    if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Warn("Timeout after " + allConnections.Count.ToString() + " seconds waiting for null packet sends to finish. " + remainingConnectionCount.ToString() + " connection waits remain. This error indicates very high send load or a possible send deadlock.");
            }
        }

原文网址: http://www.cnblogs.com/csdev

介绍开源的.net通信框架NetworkComms框架之五 心跳检测的更多相关文章

  1. 介绍开源的.net通信框架NetworkComms框架 源码分析

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了 ...

  2. 介绍开源的.net通信框架NetworkComms框架之二 传递类

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  开源地 ...

  3. 介绍开源的.net通信框架NetworkComms框架之四 消息边界

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  4. 介绍开源的.net通信框架NetworkComms框架 源码分析(二十三 )TCPConnection

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  5. 介绍开源的.net通信框架NetworkComms框架 源码分析(十九 )ConnectionIncomingData

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  6. 介绍开源的.net通信框架NetworkComms框架 源码分析(十六 ) ConnectionStatic

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  7. 介绍开源的.net通信框架NetworkComms框架 源码分析(六)SendReceiveOptions

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  8. 介绍开源的.net通信框架NetworkComms框架 源码分析(五)ReservedPacketType

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  9. 介绍开源的.net通信框架NetworkComms框架 源码分析(三)PacketHeader

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  10. 介绍开源的.net通信框架NetworkComms框架之一 首字节验证

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  开源地 ...

随机推荐

  1. Unity基于响应式编程(Reactive programming)入门

    系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoT ...

  2. PPAS Migration Toolkit document

    -----------------Migration Toolkit-----------------Migration Toolkit is a command line utility that ...

  3. Unity Tidy Tile Pack #1

    https://www.assetstore.unity3d.com/cn/#!/content/3276 版本: 1.1 下载地址 密码:mt8a

  4. winform插件机制学习

    这两天在看自定义控件,原来有太多知识没有掌握.今天看到插件机制,心里突然一亮,这个东西听了不少次,就是不知道是啥回事.这次有幸书里包含一个案例,我就跟着它一步步来.终于知道是什么回事了.这个应该在软件 ...

  5. OBD K线抓包 II

    9141的激活过程是先发WakeUp, 然后用Link: const u8 LinkCmd9141[7]  = {6,0x68,0x6A,0xF1,0x01,0x00,0xC4}; 14230的Lin ...

  6. 用NULL布局为什么不能显示

    import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing. ...

  7. Web Performance Test : IP切换/IP欺骗

    译者前言 本文翻译自<Visual Studio Performance Testing Quick Reference Guide 3.6> 有关于IP Switching的章节.< ...

  8. 11-JS基础

    JS声明变量 变量必须以字母开头 变量也能以 $ 和 _ 符号开头(不推荐这么做) 变量名称对大小写敏感(y 和 Y 是不同的变量) **提示:JavaScript 语句和 JavaScript 变量 ...

  9. ubuntu 到底是选择32位还是64位?

     ubuntu 到底是选择32位还是64位? 2011-06-03 15:16:31 标签:ubuntu linux 休闲 cpu 职场 原文出处:官方wiki原文作者:授权许可: 创作共用协议Att ...

  10. gdb多进程调试

    http://blog.csdn.net/nbabn/article/details/24984501 http://blog.csdn.net/zb872676223/article/details ...