Fork me on GitHub

采用异步来实现重新连接服务器或者重新启动服务

 

开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端!

 

 

#region 检测断线并重连OPC服务 可以强制启动OPC服务程序
/// <summary>
/// 提供外部使用
/// 重新连接事件
/// </summary>
public event LinkStateChangedEvent OnLinkStateChanged;

/// <summary>
/// 当前连接状态
/// </summary>
volatile ELinkState curLinkState = ELinkState.Unkown;
/// <summary>
/// 获取或设置当前连接状态
/// </summary>
ELinkState CurLinkState
{
get
{
lock (this)
{
return curLinkState;
}
}
set
{
lock (this)
{
curLinkState = value;
}
}
}
/// <summary>
/// 检测间隔毫秒数
/// </summary>
const int _checkInterval = 3000;
/// <summary>
/// 空闲心跳时间
/// </summary>
AutoResetEvent _waitCheckAndTryReLinkEvent = new AutoResetEvent(false);
/// <summary>
/// 是否正在检测并尝试重连
/// </summary>
volatile bool _isCheckingAndTryReLink = false;
/// <summary>
/// 获取或设置是否正在检测并尝试重连
/// </summary>
bool IsCheckingAndTryReLink
{
get
{
lock (this)
{
return _isCheckingAndTryReLink;
}
}
set
{
lock (this)
{
_isCheckingAndTryReLink = value;
}
}
}


/// <summary>
/// 启动检测并尝试重连
/// </summary>
void StartCheckAndTryReLink()
{
IsCheckingAndTryReLink = true;
BeginWaitCheckAndTryReLink();
}
/// <summary>
/// 开始等待检测并尝试重连
/// </summary>
void BeginWaitCheckAndTryReLink()
{
//开始异步等待
ThreadPool.RegisterWaitForSingleObject(_waitCheckAndTryReLinkEvent, WaitCheckAndTryReLinkCallBack, null, _checkInterval, true);
}
/// <summary>
/// 等待检测并尝试重连回调函数
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
void WaitCheckAndTryReLinkCallBack(Object state, Boolean timedOut)
{
//检测断线并重连
try
{
OPCAutomation.OPCServer service = GetOPCServer();
if (service != null)
{//连接正常
if (CurLinkState != ELinkState.Connected)
{
ELinkState oldState = CurLinkState;
CurLinkState = ELinkState.Connected;
OutLinkStateChanged(oldState, CurLinkState);
}
}
else
{//连接已断开
if (CurLinkState != ELinkState.Disconnected)
{
ELinkState oldState = CurLinkState;
CurLinkState = ELinkState.Disconnected;
OutLinkStateChanged(oldState, CurLinkState);
}
#region 尝试重连
//先注销
//try
//{
// service.Disconnect();
// // remotingClient.UnregisterChannel();
//}
//catch(Exception ex)
//{

//}
//等待一下
System.Threading.Thread.Sleep(3000);
//再重新注册
try
{
// remotingClient.RegisterChannel();
Server = new OPCAutomation.OPCServer();//重新初始化服务
Server.Connect(ServerName, IP);
//Server = service;
OPCIsConnected = true;
Task.Factory.StartNew(CreateGroupsInfos);
}
catch
{
OPCIsConnected = false;
}
#endregion
}
}
catch
{
}
//进入下一轮
if (IsCheckingAndTryReLink)
{
BeginWaitCheckAndTryReLink();
}
}
/// <summary>
/// 停止检测并尝试重连
/// </summary>
void StopCheckAndTryReLink()
{
IsCheckingAndTryReLink = false;
_waitCheckAndTryReLinkEvent.Set();
}

/// <summary>
/// 委托:连接状态发生变化
/// </summary>
/// <param name="oldState">旧状态</param>
/// <param name="newState">新状态</param>
void OutLinkStateChanged(ELinkState oldState, ELinkState newState)
{
if (OnLinkStateChanged != null)
{
//广播
LinkStateChangedEvent tempEvent = null;
foreach (Delegate del in OnLinkStateChanged.GetInvocationList())
{
try
{
tempEvent = (LinkStateChangedEvent)del;
tempEvent.BeginInvoke(oldState, newState, null, null);
}
catch
{
}
}
}
}

#endregion

 

 

public enum ELinkState
{
/// <summary>
/// 未知状态
/// </summary>
[Description("未知状态")]
Unkown = -1,
/// <summary>
/// 断开
/// </summary>
[Description("已断开")]
Disconnected = 0,
/// <summary>
/// 已连接
/// </summary>
[Description("已连接")]
Connected = 1
}

posted @ 2018-12-26 01:14  黄高林  阅读(528)  评论(2编辑  收藏  举报