Skip to content

Commit

Permalink
Merge pull request #112 from noriokun4649/Fix_new_nicolive_errors
Browse files Browse the repository at this point in the history
Fix new nicolive errors #107
  • Loading branch information
noriokun4649 authored Aug 8, 2024
2 parents 64a820b + a091a05 commit 519fe4c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ public IEnumerable<Chat> GetChats(ChannelInfo channel, DateTime time)
else
throw new ChatCollectException($"コメント取得でエラーが発生: {e}", chatCollectTask.Exception);
}
if (chatSessionTask?.IsFaulted ?? false)
{
//非同期部分で例外発生
var e = chatSessionTask.Exception.InnerExceptions.Count == 1
? chatSessionTask.Exception.InnerExceptions[0] : chatSessionTask.Exception;
// 有志のコミュニティチャンネルで生放送がされてない場合にエラー扱いされると使いづらいので
if (e is LiveNotFoundException)
notOnAir = true;
else
throw new ChatCollectException($"コメント取得でエラーが発生: {e}", chatSessionTask.Exception);
}

var liveId = liveIdResolver.Resolve(channel.NetworkId, channel.ServiceId).ToString();

Expand Down Expand Up @@ -143,6 +154,7 @@ private async Task CollectChat(CancellationToken cancellationToken)
{
try
{
await Task.Delay(2500, cancellationToken).ConfigureAwait(false);
//コメント投稿(視聴)セッションのRoomメッセージでPostKeyを取得出来るまでロックして待機
messageServers.TryTake(out var message, Timeout.Infinite);

Expand Down Expand Up @@ -205,7 +217,7 @@ public void Dispose()
}
//Waitからの例外がタスクがキャンセルされたことによるものか、通信エラー等なら無視
catch (AggregateException e) when (e.InnerExceptions.All(
innerE => innerE is OperationCanceledException || innerE is ChatReceivingException || innerE is NetworkNicoLiveCommentReceiverException
innerE => innerE is OperationCanceledException || innerE is ChatReceivingException || innerE is NetworkNicoLiveCommentReceiverException || innerE is NicoLiveCommentSenderException
))
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ public IEnumerable<Chat> GetChats(ChannelInfo channel, DateTime time)
? chatCollectTask.Exception.InnerExceptions[0] : chatCollectTask.Exception;
throw new ChatCollectException($"コメント取得でエラーが発生: {e}", chatCollectTask.Exception);
}
if (chatSessionTask?.IsFaulted ?? false)
{
//非同期部分で例外発生
var e = chatSessionTask.Exception.InnerExceptions.Count == 1
? chatSessionTask.Exception.InnerExceptions[0] : chatSessionTask.Exception;
throw new ChatCollectException($"コメント取得でエラーが発生: {e}", chatSessionTask.Exception);
}

var ret = new List<Chat>();
while (commentTagQueue.TryDequeue(out var tag))
Expand Down Expand Up @@ -176,7 +183,8 @@ public void Dispose()
}
//Waitからの例外がタスクがキャンセルされたことによるものか、通信エラー等なら無視
catch (AggregateException e) when (e.InnerExceptions.All(
innerE => innerE is OperationCanceledException || innerE is ChatReceivingException || innerE is NetworkNicoLiveCommentReceiverException
innerE => innerE is OperationCanceledException || innerE is ChatReceivingException ||
innerE is NetworkNicoLiveCommentReceiverException || innerE is NicoLiveCommentSenderException
))
{
}
Expand Down
52 changes: 44 additions & 8 deletions TVTComment/Model/NiconicoUtils/NicoLiveCommentSender.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Reactive.Linq;
Expand All @@ -12,6 +14,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Web;

namespace TVTComment.Model.NiconicoUtils
{
Expand Down Expand Up @@ -48,8 +51,9 @@ public ResponseFormatNicoLiveCommentSenderException(string response)
}
}

class ResponseErrorNicoLiveCommentSenderException : NicoLiveCommentSenderException
class LiveNotFoundException : NicoLiveCommentSenderException
{
public LiveNotFoundException(string message) : base(message) { }
}

class MessageServer
Expand All @@ -64,7 +68,7 @@ class NicoLiveCommentSender : IDisposable
private BlockingCollection<string[]> messageColl = new();
private BlockingCollection<string> errorMesColl = new();
private readonly string ua;
private int openTime;
private long openTime;
private ClientWebSocket clientWebSocket;

public NicoLiveCommentSender(NiconicoLoginSession niconicoSession)
Expand All @@ -80,11 +84,43 @@ public NicoLiveCommentSender(NiconicoLoginSession niconicoSession)

public async Task ConnectWatchSession(string liveId, BlockingCollection<MessageServer> messageServer, CancellationToken cancellationToken)
{
var resp = await httpClient.GetStringAsync("https://live.nicovideo.jp/watch/" + liveId).ConfigureAwait(false);
var webSocketUrl = Regex.Matches(resp, @"wss://.+nicovideo.jp/[/a-z0-9]+[0-9]+\?audience_token=([_a-z0-9]*)").First().Value;
var webScoketUri = new Uri(webSocketUrl);
int.TryParse(Regex.Matches(resp, @"&quot;beginTime&quot;:(?<time>[0-9]+),").First().Groups["time"].Value, out var openTime);
this.openTime = openTime;
Uri webScoketUri;

try
{
var httpResp = await httpClient.GetStringAsync("https://live.nicovideo.jp/watch/" + liveId).ConfigureAwait(false);
var dataPropsPattern = @"<script\s+[^>]*id=['""]embedded-data['""][^>]*data-props=['""]([^'""]+)['""][^>]*>";
Match match = Regex.Match(httpResp, dataPropsPattern);
if (!match.Success)
throw new NicoLiveCommentSenderException("放送情報を取得出来ませんでした。");
var dataProps = JsonDocument.Parse(HttpUtility.HtmlDecode(match.Groups[1].Value)).RootElement;
if (dataProps.TryGetProperty("site", out var site) && site.TryGetProperty("relive", out var relive) && dataProps.TryGetProperty("program",out var program))
{
var webSocketUrl = relive.GetProperty("webSocketUrl").ToString();
var notOnAir = !program.GetProperty("status").ToString().Equals("ON_AIR");
var openTime = program.GetProperty("openTime").GetInt64();

if (notOnAir || webSocketUrl.Equals(""))
throw new LiveNotFoundException("放送が終了しています。");

this.openTime = openTime;
webScoketUri = new Uri(webSocketUrl);
}
else
throw new KeyNotFoundException();
}
catch (HttpRequestException e)
{
if (e.StatusCode == HttpStatusCode.NotFound)
throw new NicoLiveCommentSenderException($"放送ページが見つかりません。放送ID:{liveId} を再確認してください");
else
throw new NicoLiveCommentSenderException($"放送ページにアクセスできません。HTTP Status:{e.Message}");
}
catch (Exception e) when (e is JsonException || e is InvalidOperationException || e is ArgumentException || e is KeyNotFoundException)
{
throw new NicoLiveCommentSenderException("放送情報を解析出来ませんでした。");
}


clientWebSocket = new ClientWebSocket();
clientWebSocket.Options.SetRequestHeader("User-Agent", ua);
Expand Down Expand Up @@ -231,7 +267,7 @@ await WsSend("{\"type\":\"postComment\",\"data\":{" +
case "NO_PERMISSION":
throw new NicoLiveCommentSenderException("APIにアクセスする権限がない");
case "NOT_ON_AIR":
throw new NicoLiveCommentSenderException("放送中ではない");
throw new LiveNotFoundException("放送中ではない");
case "BROADCAST_NOT_FOUND":
throw new NicoLiveCommentSenderException("配信情報を取得できない");
case "INTERNAL_SERVERERROR":
Expand Down

0 comments on commit 519fe4c

Please sign in to comment.