public bool Connect() { PingReply pingReply = null; try { pingReply = new Ping().Send("live.bilibili.com"); } catch (Exception) { } if (pingReply == null || pingReply.Status != IPStatus.Success) { ConnectionFailed?.Invoke("网络连接失败"); return(false); } DanmakuServer danmakuServer = GetDanmakuServer(RoomId); if (danmakuServer == null) { return(false); } switch (Protocol) { case Protocols.Tcp: DanmakuTcpClient = GetTcpConnection(danmakuServer); Stream stream = DanmakuTcpClient.GetStream(); stream.ReadTimeout = 30 * 1000 + 1000; stream.WriteTimeout = 30 * 1000 + 1000; PackReader = new BiliPackReader(stream); PackWriter = new BiliPackWriter(stream); break; case Protocols.Ws: DanmakuWebSocket = GetWsConnection(danmakuServer); PackReader = new BiliPackReader(DanmakuWebSocket); PackWriter = new BiliPackWriter(DanmakuWebSocket); break; case Protocols.Wss: DanmakuWebSocket = GetWssConnection(danmakuServer); PackReader = new BiliPackReader(DanmakuWebSocket); PackWriter = new BiliPackWriter(DanmakuWebSocket); break; } if (!InitConnection(danmakuServer)) { Disconnect(); return(false); } StartEventListener(); StartHeartbeatSender(); Connected?.Invoke(); return(true); }
public IPack[] ReadPacksAsync() { if (BaseWebSocket != null) { ArraySegment <byte> buffer = new ArraySegment <byte>(new byte[4096]); WebSocketReceiveResult webSocketReceiveResult = BaseWebSocket.ReceiveAsync(buffer, CancellationToken.None).GetAwaiter().GetResult(); BaseStream.Position = 0; BaseStream.Write(buffer.Array, 0, webSocketReceiveResult.Count); BaseStream.Position = 0; } // Pack length (4) byte[] packLengthBuffer = ReadTcpStream(BaseStream, 4); int packLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(packLengthBuffer, 0)); if (packLength < 16) { BaseStream.Flush(); // TODO : 包长度过短 throw new Exception(); } // Header length (2) byte[] headerLengthBuffer = ReadTcpStream(BaseStream, 2); int headerLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerLengthBuffer, 0)); if (headerLength != 16) { BaseStream.Flush(); // TODO : 头部长度异常 throw new Exception(); } // Data type (2) byte[] dataTypeBuffer = ReadTcpStream(BaseStream, 2); int dataTypeCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataTypeBuffer, 0)); DataTypes dataType; if (Enum.IsDefined(typeof(DataTypes), dataTypeCode)) { dataType = (DataTypes)Enum.ToObject(typeof(DataTypes), dataTypeCode); } else { dataType = DataTypes.Unknow; } // Read pack type (4) byte[] packTypeBuffer = ReadTcpStream(BaseStream, 4); int packTypeCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(packTypeBuffer, 0)); PackTypes packType; if (Enum.IsDefined(typeof(PackTypes), packTypeCode)) { packType = (PackTypes)Enum.ToObject(typeof(PackTypes), packTypeCode); } else { packType = PackTypes.Unknow; } // Read split (4) byte[] splitBuffer = ReadTcpStream(BaseStream, 4); // Read payload int payloadLength = packLength - headerLength; byte[] payloadBuffer = ReadTcpStream(BaseStream, payloadLength); // Return switch (dataType) { case DataTypes.Plain: switch (packType) { case PackTypes.Command: return(new CommandPack[] { new CommandPack(payloadBuffer) }); default: // TODO : 未知包类型 throw new Exception(); } case DataTypes.Bin: switch (packType) { case PackTypes.Popularity: return(new PopularityPack[] { new PopularityPack(payloadBuffer) }); case PackTypes.Heartbeat: return(new HeartbeatPack[] { new HeartbeatPack(payloadBuffer) }); default: // TODO : 未知包类型 throw new Exception(); } case DataTypes.Gz: List <IPack> packs = new List <IPack>(); using (MemoryStream compressedStream = new MemoryStream(payloadBuffer)) { using (GZipStream gZipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) { using (MemoryStream decompressedStream = new MemoryStream()) { gZipStream.CopyTo(decompressedStream); decompressedStream.Position = 0; while (decompressedStream.Position != decompressedStream.Length) { IPack[] innerPackes = new BiliPackReader(decompressedStream).ReadPacksAsync(); packs.AddRange(innerPackes); } } } } return(packs.ToArray()); default: // TODO : 未知数据类型 throw new Exception(); } }