/// <summary> /// 接続 /// </summary> /// <param name="server">サーバーデータ</param> /// <param name="user">ユーザーデータ</param> public void Connect(ServerInfo server, UserInfo user) { if (Status != IRCClientStatus.Disconnected) { throw new InvalidOperationException(); } try { // 準備。 m_server = server; m_user = user; m_online = false; m_threadStopFlag = false; lock (m_sendQueue) { m_sendQueue.Clear(); } lock (m_namelist) { m_namelist.Clear(); } // ソケット作成・接続 Debug.WriteLine("接続を開始します。", "IRCClient"); m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (Server.UseSsl) { m_sslHelper = new SslHelper(m_socket, Server.Name); m_sslHelper.ValidateCertEnabled = !Server.NoValidation; } m_connectAsync = m_socket.BeginConnect(server.GetEndPoint(), new AsyncCallback(OnConnected), m_socket); } catch { OnConnectionFailed(); Close(); } }
/// <summary> /// スレッドメイン処理 /// </summary> private void ThreadAction() { try { m_threadStopSignal.Reset(); Queue<EventData> eventQueue = new Queue<EventData>(); while (!m_threadStopFlag) { // 送信処理 lock (m_sendQueue) { // 送信キューがなくなるまで、キューを読み取って送信する while (m_sendQueue.Count > 0) { string sendLine = m_sendQueue.Dequeue() as string; if (sendLine != null) { Debug.WriteLine("Send> " + sendLine, "IRCClient"); m_writer.WriteLine(sendLine); if (sendLine.StartsWith("QUIT ", StringComparison.OrdinalIgnoreCase)) { m_threadStopFlag = true; } } } } // 受信処理 if (Server.UseSsl && !m_stream.DataAvailable) { m_socket.Poll(100, SelectMode.SelectRead); } while (m_stream.DataAvailable) { try { ProcessIRCMessage(eventQueue, m_reader.ReadLine()); } catch (MessageParseException) { // TODO:不明メッセージ受信 } } // イベント発生処理 if (eventQueue.Count > 0) { OnStartMessageEvents(); try { // キューにあるイベントをすべて発生させる while (eventQueue.Count > 0) { EventData eventData = eventQueue.Dequeue(); #region イベントディスパッチ if (eventData.EventKey == eventKeyOfProcessedConnection) { OnProcessedConnection(); } else if (eventData.EventKey == eventKeyOfChangedMyNickname) { OnChangedMyNickname(eventData.Argument as NickNameChangeEventArgs); } else if (eventData.EventKey == eventKeyOfChangedNickname) { OnChangedNickname(eventData.Argument as NickNameChangeEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveServerReply) { OnReceiveServerReply(eventData.Argument as ReceiveServerReplyEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveMotdMesage) { OnReceiveMotdMesage(eventData.Argument as ReceiveMessageEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveMessage) { OnReceiveMessage(eventData.Argument as ReceiveMessageEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveNotice) { OnReceiveNotice(eventData.Argument as ReceiveMessageEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveNames) { OnReceiveNames(eventData.Argument as ReceiveNamesEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveCtcpQuery) { OnReceiveCtcpQuery(eventData.Argument as CtcpEventArgs); } else if (eventData.EventKey == eventKeyOfReceiveCtcpReply) { OnReceiveCtcpReply(eventData.Argument as CtcpEventArgs); } else if (eventData.EventKey == eventKeyOfUserInOut) { OnUserInOut(eventData.Argument as UserInOutEventArgs); } else if (eventData.EventKey == eventKeyOfModeChange) { OnModeChange(eventData.Argument as ModeChangeEventArgs); } else if (eventData.EventKey == eventKeyOfTopicChange) { OnTopicChange(eventData.Argument as TopicChangeEventArgs); } else if (eventData.EventKey == eventKeyOfKick) { OnKick(eventData.Argument as KickEventArgs); } else { Debug.WriteLine("Undefined event:" + eventData.Argument.GetType().ToString()); } #endregion } } catch (Exception) { } finally { OnFinishMessageEvents(); } } Thread.Sleep(50); } } catch (ThreadAbortException) { } catch (Exception) { } finally { // 接続中であればソケットを閉じる if (m_socket.Connected) { try { m_socket.Close(); } catch (Exception) { } } if (m_sslHelper != null) { m_sslHelper.Dispose(); } // 使用したデータをクリアする m_socket = null; m_sslHelper = null; m_reader = null; m_writer = null; m_online = false; OnDisconnected(); // 処理完了シグナル送信 m_threadStopSignal.Set(); } }