繼續C# OPC Server開發,本單節實現OPC標准接口IOPCServer里的AddGroup方法代碼如下
///
<summary>
/// 新增一個 OPCGroup
/// </summary>
/// <param name="szName"> 組名。組名必須為UNICODE 碼,不能是ASC碼,而且不能和同一個客戶程序創建的其它組的名字相同。如果沒有定義組名,服務器會給它定義一個獨有的名字。 </param>
/// <param name="bActive"> 如果值為FALSE,那么組被定義為不活動的。如果為TRUE,組被定義為活動的。 </param>
/// <param name="dwRequestedUpdateRate"> 客戶程序定義的組最快的刷新速率,單位為毫秒,主要在OnDataChage 中使用。同樣說明了要求CACHED DATA 的期望速率。如果此值為0,那么服務器必須以最快的實際速率刷新。 </param>
/// <param name="hClientGroup"> 客戶程序提供的組句柄。 </param>
/// <param name="pTimeBias"> 時間戳指針。如果指針為空表示你希望使用系統默認時間戳。 </param>
/// <param name="pPercentDeadband"> 定義了死區參數。這個參數僅僅對本組內的模擬量有效。當模擬量的值變化超出死區,必須產生一個回調給客戶程序。NULL 值代表0.0,即沒有死區。 </param>
/// <param name="dwLCID"> 本組字符串操作時,服務器使用的語言。 </param>
/// <param name="phServerGroup"> 服務器為新的組產生的句柄。客戶程序將采用服務器提供的句柄來要求服務器對組進行其它的操作。 </param>
/// <param name="pRevisedUpdateRate"> 服務器返回的實際刷新速率,這個值可能與客戶程序要求的刷新速率不一樣。注意:這個值可能也比服務器實際從設備獲取數據和刷新CACHE 的速率要慢。 </param>
/// <param name="riid"> 期望接口類型 (如 IID_IOPCItemMgt) </param>
/// <param name="ppUnk"> 返回接口指針,如果操作失敗,返回NULL。 </param>
/// <returns> 操作代碼 </returns>
[PreserveSig]
public int AddGroup( string szName, bool bActive, int dwRequestedUpdateRate, int hClientGroup,
IntPtr pTimeBias, IntPtr pPercentDeadband, int dwLCID,
out int phServerGroup, out int pRevisedUpdateRate, ref Guid riid,
[MarshalAs(UnmanagedType.IUnknown), Out] out object ppUnk)
{
#region 數據准備 驗證
phServerGroup = 0;
pRevisedUpdateRate = 0;
ppUnk = null;
if (OPCDAGlobal.ServerState == OpcServerState.Failed)
{
return HRESULTS.E_FAIL;
}
if (! string.IsNullOrEmpty(szName))
{
if (_opcDAGroups.Count(p => p.GroupName == szName) > 0)
{
return HRESULTS.OPC_E_DUPLICATENAME;
}
}
#endregion
#region 獲得組名
if ( string.IsNullOrEmpty(szName))
{
int groupindex = 0;
while (! string.IsNullOrEmpty(szName))
{
string nszName = " Group " + groupindex.ToString();
if (_opcDAGroups.Count(p => p.GroupName == nszName) == 0)
{
szName = nszName;
}
groupindex++;
}
}
#endregion
#region 實例化Group 對像
OPCDAGroup opcdagroup = new OPCDAGroup( this);
pRevisedUpdateRate = OPCDAGlobal.GetRevisedKeepAliveTime(dwRequestedUpdateRate);
opcdagroup.TimeBias = Marshal.ReadInt32(pTimeBias);
float[] pdb = new float[ 1];
Marshal.Copy(pPercentDeadband, pdb, 0, 1);
opcdagroup.LCID = dwLCID;
opcdagroup.Active = bActive;
opcdagroup.GroupName = szName;
opcdagroup.PercentDeadband = pdb[ 0];
opcdagroup.RevisedUpdateRate = pRevisedUpdateRate;
opcdagroup.ClientGroup = hClientGroup;
phServerGroup = opcdagroup.ServerGroup;
ppUnk = opcdagroup;
#endregion
_opcDAGroups.Add(opcdagroup);
// 服務器實際使用的數據更新率與客戶請求的更新率不同
if (pRevisedUpdateRate != dwRequestedUpdateRate)
{
return HRESULTS.OPC_S_UNSUPPORTEDRATE;
}
return HRESULTS.S_OK;
}
/// 新增一個 OPCGroup
/// </summary>
/// <param name="szName"> 組名。組名必須為UNICODE 碼,不能是ASC碼,而且不能和同一個客戶程序創建的其它組的名字相同。如果沒有定義組名,服務器會給它定義一個獨有的名字。 </param>
/// <param name="bActive"> 如果值為FALSE,那么組被定義為不活動的。如果為TRUE,組被定義為活動的。 </param>
/// <param name="dwRequestedUpdateRate"> 客戶程序定義的組最快的刷新速率,單位為毫秒,主要在OnDataChage 中使用。同樣說明了要求CACHED DATA 的期望速率。如果此值為0,那么服務器必須以最快的實際速率刷新。 </param>
/// <param name="hClientGroup"> 客戶程序提供的組句柄。 </param>
/// <param name="pTimeBias"> 時間戳指針。如果指針為空表示你希望使用系統默認時間戳。 </param>
/// <param name="pPercentDeadband"> 定義了死區參數。這個參數僅僅對本組內的模擬量有效。當模擬量的值變化超出死區,必須產生一個回調給客戶程序。NULL 值代表0.0,即沒有死區。 </param>
/// <param name="dwLCID"> 本組字符串操作時,服務器使用的語言。 </param>
/// <param name="phServerGroup"> 服務器為新的組產生的句柄。客戶程序將采用服務器提供的句柄來要求服務器對組進行其它的操作。 </param>
/// <param name="pRevisedUpdateRate"> 服務器返回的實際刷新速率,這個值可能與客戶程序要求的刷新速率不一樣。注意:這個值可能也比服務器實際從設備獲取數據和刷新CACHE 的速率要慢。 </param>
/// <param name="riid"> 期望接口類型 (如 IID_IOPCItemMgt) </param>
/// <param name="ppUnk"> 返回接口指針,如果操作失敗,返回NULL。 </param>
/// <returns> 操作代碼 </returns>
[PreserveSig]
public int AddGroup( string szName, bool bActive, int dwRequestedUpdateRate, int hClientGroup,
IntPtr pTimeBias, IntPtr pPercentDeadband, int dwLCID,
out int phServerGroup, out int pRevisedUpdateRate, ref Guid riid,
[MarshalAs(UnmanagedType.IUnknown), Out] out object ppUnk)
{
#region 數據准備 驗證
phServerGroup = 0;
pRevisedUpdateRate = 0;
ppUnk = null;
if (OPCDAGlobal.ServerState == OpcServerState.Failed)
{
return HRESULTS.E_FAIL;
}
if (! string.IsNullOrEmpty(szName))
{
if (_opcDAGroups.Count(p => p.GroupName == szName) > 0)
{
return HRESULTS.OPC_E_DUPLICATENAME;
}
}
#endregion
#region 獲得組名
if ( string.IsNullOrEmpty(szName))
{
int groupindex = 0;
while (! string.IsNullOrEmpty(szName))
{
string nszName = " Group " + groupindex.ToString();
if (_opcDAGroups.Count(p => p.GroupName == nszName) == 0)
{
szName = nszName;
}
groupindex++;
}
}
#endregion
#region 實例化Group 對像
OPCDAGroup opcdagroup = new OPCDAGroup( this);
pRevisedUpdateRate = OPCDAGlobal.GetRevisedKeepAliveTime(dwRequestedUpdateRate);
opcdagroup.TimeBias = Marshal.ReadInt32(pTimeBias);
float[] pdb = new float[ 1];
Marshal.Copy(pPercentDeadband, pdb, 0, 1);
opcdagroup.LCID = dwLCID;
opcdagroup.Active = bActive;
opcdagroup.GroupName = szName;
opcdagroup.PercentDeadband = pdb[ 0];
opcdagroup.RevisedUpdateRate = pRevisedUpdateRate;
opcdagroup.ClientGroup = hClientGroup;
phServerGroup = opcdagroup.ServerGroup;
ppUnk = opcdagroup;
#endregion
_opcDAGroups.Add(opcdagroup);
// 服務器實際使用的數據更新率與客戶請求的更新率不同
if (pRevisedUpdateRate != dwRequestedUpdateRate)
{
return HRESULTS.OPC_S_UNSUPPORTEDRATE;
}
return HRESULTS.S_OK;
}