IceClientConnector.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using CommonNetwork_ICE.Common;
  7. using Slice;
  8. using CommonNetwork_ICE.Util;
  9. using CommonNetwork_ICE.handler;
  10. using CommonLang.Protocol;
  11. using CommonNetwork_ICE.Msg;
  12. using CommonNetwork_ICE.Session;
  13. using CommonLang.Log;
  14. using CommonLang.Concurrent;
  15. namespace CommonNetwork_ICE.Client
  16. {
  17. /// <summary>
  18. /// ICE客户端连接器,指定解码器,初始化本对象后可向指定服务器发送ICE消息,接收消息请先绑定会话侦听对象
  19. /// </summary>
  20. public abstract class IceClientConnector
  21. {
  22. private static Logger log = LoggerFactory.GetLogger("IceClientConnector");
  23. // 数据包编码解码器
  24. internal IceMessageCodec codec;
  25. // ICE接收消息委托处理类
  26. internal SenderDisp_ clientSendHandler;
  27. // 消息队列
  28. internal ClientMessageQueue messageQueue;
  29. // 会话对象
  30. internal IceClientNetSession session;
  31. // 会话消息序列号编号器
  32. private AtomicInteger msgSerialGenerator;
  33. public IceClientConnector(IceClientNetSession session)
  34. : this(session, Env.ICE_SEND_REMOTE_IP.Clone().ToString(), Env.ICE_SEND_REMOTE_PORT)
  35. {
  36. }
  37. public IceClientConnector(IceClientNetSession session, String ip, int port)
  38. {
  39. String localIp = "127.0.0.1";
  40. int localPort = 0;
  41. IceConnector netConnector = new IceConnector(
  42. Constants.SEND_INTERFACE_NAME,
  43. Constants.SERVER_SENDER_RECV_ADAPTER,
  44. ip, port,
  45. localIp,
  46. localPort);
  47. this.Connector = netConnector;
  48. this.session = session;
  49. msgSerialGenerator = new AtomicInteger(1);
  50. RecvLastSerial = -1;
  51. }
  52. internal abstract SenderDisp_ getClientSendHandler(IceClientNetSession session, IceMessageCodec Codec);
  53. // ICE连接器
  54. internal IceConnector Connector { get; set; }
  55. // 是否已经连接上服务器
  56. public bool IsConnected { internal set; get; }
  57. // 客户端收到服务器发来的最后一条关键数据包序号
  58. internal long RecvLastSerial { set; get; }
  59. /// <summary>
  60. /// 初始化ICE接收和发送端
  61. /// </summary>
  62. public abstract void Open(int localListenPort);
  63. /// <summary>
  64. /// 设定本地监听端口
  65. /// </summary>
  66. /// <param name="localListenPort">初始监听端口</param>
  67. protected void setLocalPort(int localListenPort)
  68. {
  69. int port = NetUtil.GetUsablePort(localListenPort);
  70. if (port == -1)
  71. {
  72. Env.ENV_ERR_CODE = Error.ERR_CODE_3;
  73. throw new Exception("没有找到可用端口, 基准端口:" + this.Connector.GetConnectorConfig().LocalPort);
  74. }
  75. this.Connector.GetConnectorConfig().LocalPort = port;
  76. }
  77. internal void ConnectToSever(int commType)
  78. {
  79. // 客户端接收数据处理器
  80. clientSendHandler = getClientSendHandler(session, codec);
  81. try
  82. {
  83. bool initServerSuccessed = Connector.InitRecvServer(commType, clientSendHandler);
  84. if (!initServerSuccessed)
  85. {
  86. throw new Exception("初始化服务器失败!");
  87. }
  88. Connector.InitSender(commType);
  89. Connector.Sender.Connect(this.Connector.GetConnectorConfig().LocalPort);
  90. }
  91. catch (Exception e)
  92. {
  93. log.Error("连接远程服务器IP【" + this.Connector.GetConnectorConfig().RemoteIp + "】和端口【" + this.Connector.GetConnectorConfig().RemotePort + "】异常:" + e.Message);
  94. throw e;
  95. }
  96. log.Log("正在连接服务器,请等待" + Env.CLIENT_CONNECT_WAIT_TIME / 100 + "秒。");
  97. int i = 0;
  98. while (i <= Env.CLIENT_CONNECT_WAIT_TIME)
  99. {
  100. if (IsConnected)
  101. {
  102. break;
  103. }
  104. try
  105. {
  106. Thread.Sleep(10);
  107. }
  108. catch (Exception e) { }
  109. i++;
  110. }
  111. if (IsConnected)
  112. {
  113. log.Info("已经连接上服务器IP【" + this.Connector.GetConnectorConfig().RemoteIp + "】和端口【" + this.Connector.GetConnectorConfig().RemotePort + "】,可以正常发送数据。");
  114. }
  115. else
  116. {
  117. throw new Exception("不能连接服务器,请检查远程IP【" + this.Connector.GetConnectorConfig().RemoteIp + "】和端口【" + this.Connector.GetConnectorConfig().RemotePort + "】。");
  118. }
  119. }
  120. /// <summary>
  121. /// 关闭通讯通道
  122. /// </summary>
  123. public abstract void Close();
  124. /// <summary>
  125. /// 关闭ICE网络资源
  126. /// </summary>
  127. internal void CloseConnect()
  128. {
  129. if (Connector != null)
  130. {
  131. if (Connector.Sender != null)
  132. {
  133. bool error = false;
  134. try
  135. {
  136. Connector.Sender.Close(this.Connector.GetConnectorConfig().LocalPort);
  137. }
  138. catch (Exception e)
  139. {
  140. error = true;
  141. log.Error("关闭客户端出错:" + e.Message);
  142. }
  143. if (!error)
  144. {
  145. log.Log("正在关闭客户端,请等待" + Env.CLIENT_CONNECT_WAIT_TIME / 100 + "秒。");
  146. int i = 0;
  147. while (i <= Env.CLIENT_CONNECT_WAIT_TIME)
  148. {
  149. if (!IsConnected)
  150. {
  151. break;
  152. }
  153. try
  154. {
  155. Thread.Sleep(10);
  156. }
  157. catch (Exception e) { }
  158. i++;
  159. }
  160. if (IsConnected)
  161. {
  162. log.Error("关闭客户端超时,强行终止。");
  163. IsConnected = false;
  164. }
  165. else
  166. {
  167. log.Log("关闭客户端成功。");
  168. }
  169. }
  170. }
  171. Connector.Destroy();
  172. Connector = null;
  173. }
  174. }
  175. /// <summary>
  176. /// 设定解码器
  177. /// </summary>
  178. /// <param name="codec"></param>
  179. public void SetMessageCodec(IceMessageCodec codec)
  180. {
  181. this.codec = codec;
  182. }
  183. /// <summary>
  184. /// 发送消息
  185. /// </summary>
  186. /// <param name="message">消息对象</param>
  187. public bool SendMessage(IMessage message)
  188. {
  189. if (!IsConnected)
  190. {
  191. log.Error("没有连接上服务器,不能发送数据。");
  192. session.onException(new Exception("没有连接上服务器,不能发送数据。"));
  193. return false;
  194. }
  195. if (this.codec == null)
  196. {
  197. log.Error("没有绑定解码器,不能发送数据。");
  198. session.onException(new Exception("没有绑定解码器,不能发送数据。"));
  199. return false;
  200. }
  201. TransMessage transMessage = null;
  202. try
  203. {
  204. this.codec.doEncode(message, out transMessage);
  205. }
  206. catch (Exception e)
  207. {
  208. String msg = "消息解码异常:" + message.GetType() + "" + e.Message;
  209. log.Error(msg);
  210. session.onException(e);
  211. return false;
  212. }
  213. transMessage.serial = msgSerialGenerator.GetAndIncrement();
  214. if (transMessage != null)
  215. {
  216. bool successed = SendTo(transMessage);
  217. if (!successed)
  218. {
  219. return false;
  220. }
  221. }
  222. session.onSent(message, transMessage.length);
  223. return true;
  224. }
  225. /// <summary>
  226. /// 具体的发送方法
  227. /// </summary>
  228. /// <param name="transMessage"></param>
  229. internal abstract bool SendTo(TransMessage transMessage);
  230. // 设定服务器收到已发送数据包序列号
  231. internal void SetSentLastSerial(long serial)
  232. {
  233. if (messageQueue != null)
  234. {
  235. messageQueue.LastSerial = serial;
  236. }
  237. }
  238. }
  239. }