/// <summary> /// コメントサーバーに接続します。 /// </summary> /// <remarks> /// 接続失敗時には例外が返されます。 /// </remarks> public void Connect(PlayerStatus playerStatus, CookieContainer cc) { Connect(playerStatus, cc, false, DefaultTimeout); }
/// <summary> /// 生放送に必要な情報を非同期でまとめて取得します。 /// </summary> public static LiveStreamInfo GetLiveStreamInfo(PlayerStatus playerStatus, CookieContainer cc) { if (playerStatus == null) { throw new ArgumentNullException("playerStatus"); } if (cc == null) { throw new ArgumentNullException("cc"); } // 結果などを保存するオブジェクトです。 var internalData = new InternalData() { Cookie = cc, }; var eventList = new AutoResetEvent[3] { new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false), }; // playerStatusを取得します。 internalData.LiveStreamInfo.PlayerStatus = playerStatus; eventList[0].Set(); // publishstatusを取得します。 // これは放送主にしか取得できません。 if (playerStatus.Stream.IsOwner) { BeginGetPublishStatus( playerStatus.Stream.Id, internalData, eventList[1]); } else { eventList[1].Set(); } // 放送ページの情報を取得します。 // playerstatusなどでは放送タイトルなどが一定の文字数で // 省略されてしまうためです。 BeginGetLiveInfo( playerStatus.Stream.Id, internalData, eventList[2]); // タイムアウト時間を取得します。 // (デフォルトで30秒) var timeout = WebUtil.DefaultTimeout; if (timeout < 0) { timeout = 30 * 1000; } // 各イベントが終了するのを待ちます。 foreach (var ev in eventList) { if (!ev.WaitOne(TimeSpan.FromMilliseconds(timeout))) { throw new TimeoutException( "放送情報の取得がタイムアウトしました。"); } // 例外があればそれをここで投げ返します。 var ex = internalData.Exception; if (ex != null) { throw new NicoLiveException( "GetLiveStreamInfoでエラーが発生しました。", ex); } } return internalData.LiveStreamInfo; }
/// <summary> /// コメントサーバーに接続します。 /// </summary> /// <remarks> /// 接続失敗時には例外が返されます。 /// </remarks> public void Connect(PlayerStatus playerStatus, CookieContainer cc, TimeSpan timeout) { Connect(playerStatus, cc, false, timeout); }
/// <summary> /// 全部屋からの接続が切られたときに呼ばれます。 /// </summary> private void NotifyDisconnect() { // ここでイベントが呼ばれます。 FireDisconnected(); lock (SyncRoot) { this.connectedRoomCount = 0; this.currentRoomIndex = -1; this.cookieContainer = null; this.playerStatus = null; this.publishStatus = null; this.roomList.Clear(); } ClearOwnerComment(); }
/// <summary> /// 生放送に必要な情報を非同期でまとめて取得します。 /// </summary> public static LiveStreamInfo GetLiveStreamInfo(PlayerStatus playerStatus, CookieContainer cc) { if (playerStatus == null) { throw new ArgumentNullException("playerStatus"); } if (cc == null) { throw new ArgumentNullException("cc"); } // 結果などを保存するオブジェクトです。 var internalData = new InternalData() { Cookie = cc, }; var eventList = new AutoResetEvent[3] { new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false), }; // playerStatusを取得します。 internalData.LiveStreamInfo.PlayerStatus = playerStatus; eventList[0].Set(); // publishstatusを取得します。 // これは放送主にしか取得できません。 if (playerStatus.Stream.IsOwner) { BeginGetPublishStatus( playerStatus.Stream.Id, internalData, eventList[1]); } else { eventList[1].Set(); } // 放送ページの情報を取得します。 // playerstatusなどでは放送タイトルなどが一定の文字数で // 省略されてしまうためです。 BeginGetLiveInfo( playerStatus.Stream.Id, internalData, eventList[2]); // タイムアウト時間を取得します。 // (デフォルトで30秒) var timeout = WebUtil.DefaultTimeout; if (timeout < 0) { timeout = 30 * 1000; } // 各イベントが終了するのを待ちます。 foreach (var ev in eventList) { if (!ev.WaitOne(TimeSpan.FromMilliseconds(timeout))) { throw new TimeoutException( "放送情報の取得がタイムアウトしました。"); } // 例外があればそれをここで投げ返します。 var ex = internalData.Exception; if (ex != null) { throw new NicoLiveException( "GetLiveStreamInfoでエラーが発生しました。", ex); } } return(internalData.LiveStreamInfo); }
/// <summary> /// 公式放送のコメントサーバーに接続します。 /// </summary> /// <remarks> /// 接続失敗時には例外が返されます。 /// </remarks> public void ConnectToOfficial(string filepath, CookieContainer cc, TimeSpan timeout) { lock (ConnectLock) { // 各コメントルームの情報を取得します。 var roomInfoList = Detail.OfficialLiveInfoCreator .GetAllRoomInfoFromXml(filepath); var roomList = new List<CommentRoom>(); // 各コメントルームに接続します。 for (var i = 0; i < roomInfoList.Count(); ++i) { var room = new CommentRoom(this, roomInfoList[i], i); // 接続に失敗した場合、例外が返ります。 room.Connect(cc, timeout); roomList.Add(room); } Disconnect(); lock (SyncRoot) { this.connectedRoomCount = 0; this.playerStatus = null; this.publishStatus = null; this.liveInfo = null; this.roomList = roomList; this.currentRoomIndex = -1; this.cookieContainer = cc; } // フィールド値を設定した後に、OnConnectedRoomを呼びます。 foreach (var room in ClonedCommentRoomList) { OnConnectedRoom(room); } // 接続時のイベントを発生させます。 FireConnected(); } }
/// <summary> /// 全コメントルームのポート情報などを取得します。 /// </summary> private CommentRoomInfo[] GetAllRoomInfo(PlayerStatus playerStatus, int communityLevel) { var creator = Detail.LiveInfoCreatorUtil.CreateCreator( playerStatus.Stream.ProviderType); return creator.GetAllRoomInfo(playerStatus, communityLevel); }
/// <summary> /// コメントサーバーに接続します。 /// </summary> /// <remarks> /// 接続失敗時には例外が返されます。 /// </remarks> public void Connect(PlayerStatus playerStatus, CookieContainer cc, bool currentRoomOnly, TimeSpan timeout) { lock (ConnectLock) { if (playerStatus == null) { throw new ArgumentNullException("playerStatus"); } // 例外が発生する可能性があります。 var streamInfo = LiveUtil.GetLiveStreamInfo(playerStatus, cc); // 各コメントルームの情報を取得します。 var roomInfoList = GetAllRoomInfo( streamInfo.PlayerStatus, streamInfo.LiveInfo.CommunityLevel); var currentRoomIndex = FindRoomIndex( playerStatus.MS.Port, roomInfoList); var roomList = new List<CommentRoom>(); // 各コメントルームに接続します。 for (var i = 0; i < roomInfoList.Count(); ++i) { if (currentRoomOnly && i != currentRoomIndex) { roomList.Add(null); continue; } var room = new CommentRoom(this, roomInfoList[i], i); // 接続に失敗した場合、例外が返ります。 room.Connect(cc, timeout); roomList.Add(room); } Disconnect(); lock (SyncRoot) { this.connectedRoomCount = 0; this.playerStatus = streamInfo.PlayerStatus; this.publishStatus = streamInfo.PublishStatus; this.liveInfo = streamInfo.LiveInfo; this.roomList = roomList; this.currentRoomIndex = currentRoomIndex; this.cookieContainer = cc; } // フィールド値を設定した後に、OnConnectedRoomを呼びます。 foreach (var room in ClonedCommentRoomList) { OnConnectedRoom(room); } // 接続時のイベントを発生させます。 FireConnected(); } }