Exemplo n.º 1
0
        public async Task ConnectAsync(string url, Option?option = null)
        {
            if (option.HasValue)
            {
                parser = new DanMuPa(option.Value);
            }

            using (tcpClient = new TcpClient())
            {
                // 获得roomid
                var httpClient = new HttpClient();
                var bodyText   = await httpClient.GetStringAsync(url);

                var reg    = new Regex(@"var\s+ROOMID\s+=\s+(\w+);");
                var match  = reg.Match(bodyText);
                var roomId = match.Groups[1].Value;

                // 获得tcp服务器地址
                var xmlText = await httpClient.GetStringAsync($"http://live.bilibili.com/api/player?id=cid:{roomId}");

                var xml  = XElement.Parse($"<root>{xmlText}</root>");
                var host = xml.Element("dm_server").Value;
                var port = int.Parse(xml.Element("dm_port").Value);

                // 链接房间
                var data = OpenMsg(roomId);
                Console.WriteLine($"Connect to Room {roomId} on {host}:{port}");

                // 连接服务器
                await tcpClient.ConnectAsync(host, port);

                using (var stream = tcpClient.GetStream())
                {
                    await stream.WriteAsync(data, 0, data.Length);

                    heartbeat = Task.Run(async() =>
                    {
                        var at           = DateTimeOffset.Now.ToUnixTimeSeconds();
                        Byte[] heartBeat = HeartbeatMsg();
                        while (true)
                        {
                            if (tcpClient.Connected && stream.CanWrite)
                            {
                                SpinWait.SpinUntil(() => DateTimeOffset.Now.ToUnixTimeSeconds() - at >= 29);
                                await stream.WriteAsync(heartBeat, 0, heartBeat.Length);
                                at = DateTimeOffset.Now.ToUnixTimeSeconds();
                                Debug.WriteLine("Heartbeat");
                            }
                            else
                            {
                                Debug.WriteLine("Disconnect");
                                return;
                            }
                        }
                    });

                    reciever = Task.Run(async() =>
                    {
                        var buffer = new Byte[4];
                        var at     = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                        while (true)
                        {
                            if (tcpClient.Available > 0 && stream.CanRead)
                            {
                                buffer = new Byte[4];
                                await stream.ReadAsync(buffer, 0, 4);
                                var MsgLength    = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0)) - 4;
                                buffer           = new Byte[MsgLength];
                                var recievedByte = 0;
                                while (recievedByte < MsgLength)
                                {
                                    recievedByte += await stream.ReadAsync(buffer, recievedByte, MsgLength - recievedByte);
                                }
                                var respText = parser.ParsePackage(buffer);
                                if (!string.IsNullOrWhiteSpace(respText))
                                {
                                    Console.WriteLine(respText);
                                }
                                Debug.WriteLine(BitConverter.ToString(buffer));
                            }
                            else
                            {
                                SpinWait.SpinUntil(() => DateTimeOffset.Now.ToUnixTimeMilliseconds() - at >= 300);
                                at = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                            }
                        }
                    });

                    reciever.Wait();
                }
            }
        }
Exemplo n.º 2
0
 public DanMuJi()
 {
     parser = new DanMuPa();
 }