我写了一个叫做DonationListener
的复杂类。此类具有一个名为onDonation
的属性,该属性具有一个在捐赠发生时将被调用的函数。在一个简单的控制台程序中,它可以正常工作,但在更复杂的WinForms应用程序中,则不能。我很确定班上没有错误。因此,我认为问题在于使用它。我的班级使用WebSockets,因此我决定与提琴手一起检查在第一次捐赠事件之后连接是否丢失,答案是否定的,连接是否正确,并发送应调用onDonation
的程序包。这是代码
public string donation_password;
DonationListener dl;
public System.Windows.Forms.PictureBox[,] eliteCards;
public mainForm()
{
InitializeComponent();
initializeDonation();
}
public void initializeDonation()
{
donation_password = db.getPassword();
dl = new DonationListener(donation_password);
dl.OnDonation = donation =>
{
overlay ol = new overlay();
string username = donation["username"].ToString();
User toRide = db.getUserByField(username);
ol.Show();
ol.ride(toRide);
};
Task t = new Task(() => {
dl.DoListen();
});
t.Start();
}
完整类DonationListener(如果您需要它的话)
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace RacheM
{
public class DonationListener
{
private string addUserTemplate = "69:42[\"add-user\",{{\"token\":\"{0}\",\"type\":\"alert_widget\"}}]";
public Action<JObject> OnDonation = null;
private readonly string _token;
public DonationListener(string token)
{
_token = token;
}
public void DoListen()
{
var result =
DoRequest("GET", "https://socket.donationalerts.ru/socket.io/?EIO=3&transport=polling"); //&t=MYotE0N
var sid = ExtractToken(result);
if (string.IsNullOrEmpty(sid))
{
throw new Exception("Failed to get sid");
}
var cookie = new Cookie("io", sid, "/", "socket.donationalerts.ru");
DoRequest(
"POST",
$"https://socket.donationalerts.ru/socket.io/?EIO=3&transport=polling&sid={sid}",
string.Format(addUserTemplate, _token),
cookie
);
var waiter = DoWebSocket($"wss://socket.donationalerts.ru/socket.io/?EIO=3&transport=websocket&sid={sid}",
cookie);
waiter.GetAwaiter().GetResult();
}
private static string ExtractToken(string strWidthToken)
{
var m = Regex.Match(strWidthToken, "\"sid\":\"(?<token>[^\"]+)\"");
return m.Groups["token"].Value;
}
private static string DoRequest(string method, string url, string data = "", Cookie cookie = null)
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create(url);
httpWebRequest.Method = method;
httpWebRequest.Accept = "*/*";
httpWebRequest.Headers.Add("Origin", "https://www.donationalerts.com");
httpWebRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate, br");
httpWebRequest.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.9");
httpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36";
httpWebRequest.Referer = "https://www.donationalerts.com/widget/alerts?group_id=1&token=mcq71m8KVIsojvo5ukFZ";
if (method == "GET")
{
//httpWebRequest.Headers.Remove("Content-Length");
httpWebRequest.ContentLength = 0;
}
else
{
httpWebRequest.ContentType = "text/plain;charset=UTF-8";
}
if (cookie != null)
{
if (httpWebRequest.CookieContainer == null)
{
httpWebRequest.CookieContainer = new CookieContainer();
}
httpWebRequest.CookieContainer.Add(cookie);
}
if (method == "POST" && !string.IsNullOrEmpty(data))
{
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
var streamReader = new StreamReader(httpResponse.GetResponseStream());
if(streamReader == null)
{
throw new Exception("Connection error");
}
using (streamReader)
{
return streamReader.ReadToEnd();
}
}
private async Task DoWebSocket(string url, Cookie cookie)
{
using (var ws = new ClientWebSocket())
{
var serverUri = new Uri(url);
ws.Options.Cookies = new CookieContainer();
ws.Options.Cookies.Add(cookie);
await ws.ConnectAsync(serverUri, CancellationToken.None);
var cts = new CancellationTokenSource();
Task.Factory.StartNew(
async () =>
{
while (true)
{
try
{
string srcMessage = string.Empty;
ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]);
using (var ms = new MemoryStream())
{
WebSocketReceiveResult result= null;
do
{
result = await ws.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, result.Count);
} while (!result.EndOfMessage);
ms.Seek(0, SeekOrigin.Begin);
if (result.MessageType == WebSocketMessageType.Text)
{
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
srcMessage = reader.ReadToEnd();
}
}
}
if (string.IsNullOrEmpty(srcMessage)) continue;
if (srcMessage.IndexOf("42[\"donation", StringComparison.Ordinal) == 0)
{
OnDonation?.Invoke(ParseDonateMessage(srcMessage));
}
else
{
Console.WriteLine("no donate msg: " + srcMessage);
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
await SendWsMessage(ws, "2probe");
await SendWsMessage(ws, "5");
while (ws.State == WebSocketState.Open)
{
await SendWsMessage(ws, "2");
Thread.Sleep(25000);
}
}
}
private static async Task SendWsMessage(WebSocket ws, string message)
{
var sendBytes = Encoding.UTF8.GetBytes(message);
var cts = new CancellationTokenSource();
var sendBuffer = new ArraySegment<byte>(sendBytes);
await
ws.SendAsync(sendBuffer, WebSocketMessageType.Text, endOfMessage: true,
cancellationToken: cts.Token);
}
private static JObject ParseDonateMessage(string rcvMsg)
{
rcvMsg = rcvMsg.Replace("42[\"donation\",\"", "");
rcvMsg = rcvMsg.Substring(0, rcvMsg.Length - 2);
return (JObject)JsonConvert.DeserializeObject(Regex.Unescape(rcvMsg));
}
}
}
答案 0 :(得分:0)
也许您应该尝试通过以下方式使此函数重复自身:
bool RunFlag = true // can be set to false somewhere else
public void DoListen()
{
while(RunFlag) {
var result =
DoRequest("GET", "https://socket.donationalerts.ru/socket.io/?EIO=3&transport=polling"); //&t=MYotE0N
var sid = ExtractToken(result);
if (string.IsNullOrEmpty(sid))
{
throw new Exception("Failed to get sid");
}
var cookie = new Cookie("io", sid, "/", "socket.donationalerts.ru");
DoRequest(
"POST",
$"https://socket.donationalerts.ru/socket.io/?EIO=3&transport=polling&sid={sid}",
string.Format(addUserTemplate, _token),
cookie
);
var waiter = DoWebSocket($"wss://socket.donationalerts.ru/socket.io/?EIO=3&transport=websocket&sid={sid}",
cookie);
waiter.GetAwaiter().GetResult();
}
}