DiscoverServerDlg.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* ========================================================================
  2. * Copyright (c) 2005-2019 The OPC Foundation, Inc. All rights reserved.
  3. *
  4. * OPC Foundation MIT License 1.00
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use,
  10. * copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following
  13. * conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be
  16. * included in all copies or substantial portions of the Software.
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  19. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  24. * OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. * The complete license agreement can be found here:
  27. * http://opcfoundation.org/License/MIT/1.00/
  28. * ======================================================================*/
  29. using System;
  30. using System.Collections.Generic;
  31. using System.ComponentModel;
  32. using System.Drawing;
  33. using System.Text;
  34. using System.Windows.Forms;
  35. using Opc.Ua;
  36. using Opc.Ua.Client;
  37. namespace OpcUaHelper.Forms
  38. {
  39. /// <summary>
  40. /// Prompts the user to specify a host name and discovers the servers.
  41. /// </summary>
  42. public partial class DiscoverServerDlg : Form
  43. {
  44. #region Constructors
  45. /// <summary>
  46. /// Creates an empty form.
  47. /// </summary>
  48. public DiscoverServerDlg()
  49. {
  50. InitializeComponent();
  51. this.Icon = ClientUtils.GetAppIcon();
  52. }
  53. #endregion
  54. #region Private Fields
  55. private ApplicationConfiguration m_configuration;
  56. #endregion
  57. #region Public Interface
  58. /// <summary>
  59. /// Shows the dialog.
  60. /// </summary>
  61. /// <param name="configuration">The client applicatio configuration.</param>
  62. /// <returns>The selected endpoint url</returns>
  63. public string ShowDialog(ApplicationConfiguration configuration)
  64. {
  65. return ShowDialog(configuration, null);
  66. }
  67. /// <summary>
  68. /// Shows the dialog.
  69. /// </summary>
  70. /// <param name="configuration">The client applicatio configuration.</param>
  71. /// <param name="hostName">The default host name.</param>
  72. /// <returns>The selected endpoint url</returns>
  73. public string ShowDialog(ApplicationConfiguration configuration, string hostName)
  74. {
  75. m_configuration = configuration;
  76. if (String.IsNullOrEmpty(hostName))
  77. {
  78. ValueTB.Text = System.Net.Dns.GetHostName();
  79. }
  80. else
  81. {
  82. ValueTB.Text = hostName;
  83. }
  84. // display the dialog.
  85. if (ShowDialog() != DialogResult.OK)
  86. {
  87. return null;
  88. }
  89. return ServersLB.SelectedItem as string;
  90. }
  91. #endregion
  92. #region Private Methods
  93. /// <summary>
  94. /// Gets the endpoints for the host.
  95. /// </summary>
  96. /// <param name="hostName">Name of the host.</param>
  97. private string[] GetEndpoints(string hostName)
  98. {
  99. List<string> urls = new List<string>();
  100. try
  101. {
  102. Cursor = Cursors.WaitCursor;
  103. // set a short timeout because this is happening in the drop down event.
  104. EndpointConfiguration configuration = EndpointConfiguration.Create(m_configuration);
  105. configuration.OperationTimeout = 20000;
  106. // Connect to the local discovery server and find the available servers.
  107. using (DiscoveryClient client = DiscoveryClient.Create(new Uri(Utils.Format("opc.tcp://{0}:4840", hostName)), configuration))
  108. {
  109. ApplicationDescriptionCollection servers = client.FindServers(null);
  110. // populate the drop down list with the discovery URLs for the available servers.
  111. for (int ii = 0; ii < servers.Count; ii++)
  112. {
  113. // don't show discovery servers.
  114. if (servers[ii].ApplicationType == ApplicationType.DiscoveryServer)
  115. {
  116. continue;
  117. }
  118. for (int jj = 0; jj < servers[ii].DiscoveryUrls.Count; jj++)
  119. {
  120. string discoveryUrl = servers[ii].DiscoveryUrls[jj];
  121. // Many servers will use the '/discovery' suffix for the discovery endpoint.
  122. // The URL without this prefix should be the base URL for the server.
  123. if (discoveryUrl.EndsWith("/discovery"))
  124. {
  125. discoveryUrl = discoveryUrl.Substring(0, discoveryUrl.Length - "/discovery".Length);
  126. }
  127. // remove duplicates.
  128. if (!urls.Contains(discoveryUrl))
  129. {
  130. urls.Add(discoveryUrl);
  131. }
  132. }
  133. }
  134. }
  135. return urls.ToArray();
  136. }
  137. catch (Exception)
  138. {
  139. return urls.ToArray();
  140. }
  141. finally
  142. {
  143. Cursor = Cursors.Default;
  144. }
  145. }
  146. #endregion
  147. #region Event Handlers
  148. private void OkBTN_Click(object sender, EventArgs e)
  149. {
  150. try
  151. {
  152. if (Utils.ParseUri(ServersLB.SelectedItem as string) != null)
  153. {
  154. DialogResult = DialogResult.OK;
  155. }
  156. }
  157. catch (Exception exception)
  158. {
  159. ClientUtils.HandleException(this.Text, exception);
  160. }
  161. }
  162. private void ServersLB_SelectedIndexChanged(object sender, EventArgs e)
  163. {
  164. try
  165. {
  166. OkBTN.Enabled = Utils.ParseUri(ServersLB.SelectedItem as string) != null;
  167. }
  168. catch (Exception exception)
  169. {
  170. ClientUtils.HandleException(this.Text, exception);
  171. }
  172. }
  173. private void FindBTN_Click(object sender, EventArgs e)
  174. {
  175. try
  176. {
  177. Cursor.Current = Cursors.WaitCursor;
  178. ServersLB.Items.Clear();
  179. ServersLB.Items.Add("No endpoints found.");
  180. if (String.IsNullOrEmpty(ValueTB.Text))
  181. {
  182. return;
  183. }
  184. ServersLB.Items.Clear();
  185. foreach (string url in GetEndpoints(ValueTB.Text))
  186. {
  187. ServersLB.Items.Add(url);
  188. }
  189. if (ServersLB.Items.Count == 0)
  190. {
  191. ServersLB.Items.Add("No endpoints found.");
  192. }
  193. }
  194. catch (Exception exception)
  195. {
  196. ClientUtils.HandleException(this.Text, exception);
  197. }
  198. finally
  199. {
  200. Cursor.Current = Cursors.Default;
  201. }
  202. }
  203. private void ValueTB_TextChanged(object sender, EventArgs e)
  204. {
  205. ServersLB.Items.Clear();
  206. }
  207. #endregion
  208. }
  209. }