/// <summary> /// 在指定的 List<ConnectionListItem> 中寻找以指定 <see cref="Kei.KEndPoint"/> 区分的 <see cref="Kei.KNetwork.ConnectionListItem"/>,并返回查找结果。 /// </summary> /// <param name="list">要在其中查找的 List<ConnectionListItem>。</param> /// <param name="endPoint">作为指定键的 <see cref="Kei.KEndPoint"/>。</param> /// <param name="index">输出一个 <see cref="System.Int32"/>。如果找到了,这个值是找到的项的索引;如果未找到,则该值无效。</param> /// <returns>一个 <see cref="Kei.KNetwork.ConnectionListItem"/>,指示找到的项;或者 null,表示没找到。</returns> public static ConnectionListItem FindConnectionListItem(this List <ConnectionListItem> list, KEndPoint endPoint, out int index) { if (list == null) { index = 0; return(null); } ConnectionListItem cli = null; int i = 0; index = 0; lock (list) { foreach (var item in list) { if (item.ClientLocation.Equals(endPoint)) { index = i; cli = item; break; } i++; } } return(cli); }
/// <summary> /// 将一个端点(对应一个客户端)添加至连接列表。如果列表中已有此端点,则返回对应的连接列表项。 /// <para>注意,本方法执行中会为 ConnectionList 加锁。</para> /// </summary> /// <param name="endPoint">要添加的客户端的端点。</param> /// <returns>一个 <see cref="Kei.KNetwork.ConnectionListItem"/>,表示添加或者找到的连接列表项。</returns> private ConnectionListItem AddToConnectionList(KEndPoint endPoint) { if (endPoint.Equals(LocalKEndPoint)) { Logger.Log("KClient::AddToConnectionList(KEndPoint): 不能加入自己"); return(null); } Logger.Log("KClient::AddToConnectionList(KEndPoint)" + Environment.NewLine + "待加入的端点: " + endPoint.ToString()); int index; var connItem = ConnectionList.FindConnectionListItem(endPoint, out index); if (connItem == null) { Logger.Log("在列表中未发现,即将加入。"); connItem = new ConnectionListItem(endPoint); lock (ConnectionList) { ConnectionList.Add(connItem); EventHelper.RaiseEvent(ConnectionListChanged, this, EventArgs.Empty); } } return(connItem); }
/// <summary> /// 处理 ClientExitNetwork 消息。 /// </summary> /// <param name="args">处理时所需要的信息。</param> private void HandleClientExitNetwork(HandleMessageArgs args) { Logger.Log("收到消息: 客户端离开分布网络。"); KEndPoint remoteEndPoint = args.Message.Header.SourceEndPoint; // 只是简单的移除 int clItemIndex; ConnectionListItem item = ConnectionList.FindConnectionListItem(remoteEndPoint, out clItemIndex); if (item != null) { Logger.Log("找到项目并移除。"); lock (ConnectionList) { // 一样,应该不用担心前面的项被移动到后面去导致索引错误的事情吧 ConnectionList.RemoveAt(clItemIndex); EventHelper.RaiseEvent(ConnectionListChanged, this, EventArgs.Empty); } } Logger.Log("转发消息。"); // 转发 BroadcastMessage(args.Message); }