/// <summary> /// 指定された時間以前の過去ログを取得する /// </summary> /// <param name="data"></param> /// <param name="cookies"></param> /// <param name="userId"></param> /// <param name="when">取得開始時間</param> /// <param name="resFrom"></param> /// <returns></returns> internal static Chat[] ReceiveLog(IMessageServerStatus data, System.Net.CookieContainer cookies, int userId, DateTime when, int resFrom) { List<Chat> results = new List<Chat>(1000); TcpClient tcpClient = null; try { Waybackkey key = Waybackkey.GetInstance(data.Thread, cookies); if (key != null) { bool timeouted = false; using (System.Threading.ManualResetEvent m = new System.Threading.ManualResetEvent(false)) { tcpClient = new TcpClient(); tcpClient.SendTimeout = 1000; tcpClient.ReceiveTimeout = 1000; AsyncCallback ac = (AsyncCallback)delegate(IAsyncResult ar) { if (!timeouted) { m.Set(); TcpClient tcp = (TcpClient)ar.AsyncState; tcp.EndConnect(ar); } }; tcpClient.BeginConnect(data.Address, data.Port, ac, tcpClient); // 既定時間以内に接続できない場合は失敗とする if (!m.WaitOne(ApiSettings.Default.DefaultConnectionTimeout, false)) { timeouted = true; throw new Exception("過去ログ取得:コネクションタイムアウト"); } } // NetworkStreamは自動的に開放されないのでusingで囲む using (NetworkStream ns = tcpClient.GetStream()) { string msg = String.Format(ApiSettings.Default.WaybackThreadStartMessageFormat, data.Thread, resFrom, Utility.DateTimeToUnixTime(when), key.Value, userId); byte[] sendBytes = System.Text.Encoding.UTF8.GetBytes(msg + '\0'); ns.Write(sendBytes, 0, sendBytes.Length); byte[] buffer = new byte[ApiSettings.Default.ReceiveBufferSize]; int last = 0; //DataAvailableはすべて取得しきる前にfalseを返してしまうので使えない while (ns.CanRead) { int b = ns.ReadByte(); if (b == -1) { break; } int i; for (i = 0; b != (int)'\0' && b != -1 && i < buffer.Length; i++, b = ns.ReadByte()) { buffer[i] = (byte)b; } string block = System.Text.Encoding.UTF8.GetString(buffer, 0, i); if (block.StartsWith("<chat")) { Chat chat = null; try { chat = new Chat(block); } catch (Exception ex) { chat = null; Logger.Default.LogErrorMessage(ex.Message); } if (chat != null) { results.Add(chat); // 指定数読み込んだ場合は終了 if (chat.No == last) { break; } } } else if (block.StartsWith("<thread")) { ThreadHeader th = new ThreadHeader(block); last = th.LastRes; // コメントがない状態ではエラーが発生するのでBreakする if (last == 0) { break; } } } } } } catch (System.IO.IOException) { } catch (Exception ex) { Logger.Default.LogException(ex); } finally { if (tcpClient != null) { tcpClient.Close(); } } return results.ToArray(); }
/// <summary> /// 放送の過去ログをすべて取得する /// </summary> /// <param name="data"></param> /// <param name="cookies"></param> /// <param name="userId"></param> /// <returns></returns> public static Chat[] ReceiveAllLog(IMessageServerStatus data, System.Net.CookieContainer cookies, int userId) { Chat[] results = null; DateTime when = DateTime.Now; while (true) { Chat[] chats = ReceiveLog(data, cookies, userId, when, -1000); if (0 < chats.Length && results == null) { results = new Chat[chats[chats.Length - 1].No]; } for (int i = 0; i < chats.Length; i++) { results[chats[0].No + i - 1] = chats[i]; } if (chats.Length != 0) { if (1 < chats[0].No) { when = chats[0].Date; } else { break; } } else { break; } } return results; }
/// <summary> /// 放送の過去ログをすべて取得する /// </summary> /// <param name="data"></param> /// <param name="userId"></param> /// <returns></returns> public static Chat[] ReceiveAllLog(IMessageServerStatus data, int userId) { if (LoginManager.DefaultCookies != null) { return ReceiveAllLog(data, LoginManager.DefaultCookies, userId); } return null; }
/// <summary> /// コメント取得を開始する /// </summary> /// <param name="data"></param> /// <param name="resFrom"></param> /// <returns>成功・失敗</returns> public bool Connect(IMessageServerStatus data, int resFrom) { this.Initialize(); lock (this) { try { bool timeouted = false; using (System.Threading.ManualResetEvent m = new System.Threading.ManualResetEvent(false)) { _tcpClient = new TcpClient(); _tcpClient.SendTimeout = 1000; _tcpClient.ReceiveTimeout = 1000; AsyncCallback ac = (AsyncCallback)delegate(IAsyncResult ar) { if (!timeouted) { m.Set(); TcpClient tcp = (TcpClient)ar.AsyncState; tcp.EndConnect(ar); } }; // 既定時間以上応答が無かった場合はタイムアウト _tcpClient.BeginConnect(data.Address, data.Port, ac, _tcpClient); if (!m.WaitOne(ApiSettings.Default.DefaultConnectionTimeout, false)) { timeouted = true; throw new Exception("コメント受信:サーバーコネクションタイムアウト"); } } string msg = String.Format(ApiSettings.Default.ThreadStartMessageFormat, data.Thread, resFrom); SendMessge(msg); NetworkStream ns = _tcpClient.GetStream(); StateObject obj = new StateObject(ApiSettings.Default.ReceiveBufferSize, ns); ns.BeginRead(obj.Buffer, 0, obj.BufferSize, new AsyncCallback(ReadCallback), obj); // キャンセルイベントをリセット // 切断されるまでセットされない _cancelEvent.Reset(); return true; } catch (Exception ex) { Logger.Default.LogException(ex); } } return false; }