/// <summary> /// Queue a request for data to the database. /// The DatabaseRequest will always be executed on the database /// thread. It should be used to retrieve data from the database. /// The DatabaseCallback will be executed in the loop specified /// in the third argument. This can be used to process the data. /// </summary> /// <typeparam name="T">The type of data you want to request</typeparam> /// <param name="request">The request to execute on the database thread. Needs to return collection of data</param> /// <param name="callback">The callback to execute in the specified loop when the data has been retrieved</param> /// <param name="loop">The loop in which to call the callback</param> public static void QueueDatabaseRequest <T>(DatabaseRequest <T> request, DatbaseCallback <T> callback, TickLoop loop) where T : class { App.Console?.Print($"Queued a DBRequest", Colors.LimeGreen); DatabaseLoop.EnqueueAction(() => { var results = request.Invoke(Database); int count; if (results != null) { count = results.Count; loop.EnqueueAction(() => callback.Invoke(results)); } else { count = 0; loop.EnqueueAction(() => callback.Invoke(new List <T>())); } App.Console?.Print($"Retrieved {count} items from DB, queueing callback", Colors.LimeGreen); }); }
/// <summary> /// 接收数据 /// </summary> /// <param name="socket">客户端Socket对象</param> private void ReceiveMessage(Socket socket) { bool isMain = true; //是否为主端口 string clientID = string.Empty; //客户端ID IPEndPoint clientIPEndPoint = (IPEndPoint)socket.RemoteEndPoint; //客户端网络终结点 bool isFirstConnection = true; //是否为首次连接 byte[] dataBuffer = new byte[1024 * 1024]; //缓冲区 bool isFirstReceive = true; //是否为首次接收数据 Transmit transmit = null; //传输对象 double dataSize = 0.0; //数据总大小 double receiveBytes = 0.0; //已接收的字节数 int targetPort = -1; //发送目标端口 while (true) { int readBytes = 0; if (socket.Poll(-1, SelectMode.SelectRead) == true) { if (!ServerState) { break; } try { readBytes = socket.Receive(dataBuffer, dataBuffer.Length, SocketFlags.None); if (readBytes == 0) { if (isMain) { CloseClient(clientID); break; } CloseClientPort(clientID, clientIPEndPoint.Port); break; } } catch (Exception exception) { if (isMain) { CloseClient(clientID, false, exception); break; } CloseClientPort(clientID, clientIPEndPoint.Port, false, exception); break; } } //首次连接 if (isFirstConnection) { isFirstConnection = false; clientID = Encoding.UTF8.GetString(dataBuffer, 0, readBytes); if (clientCollection.AddClient(clientID, clientIPEndPoint, socket)) { ServerMessage?.Invoke(this, new ServerNotifyEventArgs($"客户端 {clientID}({clientIPEndPoint}) 已连接")); } else { if (!clientCollection.AddPort(clientID, clientIPEndPoint.Port, socket)) { break; } isMain = false; ServerMessage?.Invoke(this, new ServerNotifyEventArgs($"客户端 {clientID} 的 {clientIPEndPoint.Port} 端口已连接")); } socket.Send(new byte[] { 1 }); continue; } //首次接收数据 if (isFirstReceive) { isFirstReceive = false; transmit = BytesConvert.BytesToObject(dataBuffer, readBytes, "MiniSocket.Transmitting") as Transmit; if (transmit?.Parameter == null) { ResetParameter(ref isFirstReceive, ref transmit, ref dataSize, ref receiveBytes); continue; } if (isMain) { string[] parameters = transmit.Parameter.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); switch (transmit.DataType) { case DataType.Text: if (!Forward(transmit, dataBuffer, readBytes)) { return; } break; case DataType.Image: if (parameters.Length == 2) { if (double.TryParse(parameters[1], out dataSize)) { if (!Forward(transmit, dataBuffer, readBytes)) { return; } continue; } } break; case DataType.Request: if (transmit.Parameter.StartsWith("Database")) { if (parameters.Length == 2) { var result = DatabaseRequest?.Invoke(this, new DatabaseEventArgs(parameters[1], transmit.Object))?.Result; if (result != null) { transmit.Parameter = "Client;RequestResult"; transmit.Object = result; byte[] buffer = BytesConvert.ObjectToBytes(transmit); if (!Forward(transmit, buffer, buffer.Length)) { return; } } } } break; } ResetParameter(ref isFirstReceive, ref transmit, ref dataSize, ref receiveBytes); continue; } if (transmit.DataType == DataType.File) { string[] parameters = transmit.Parameter.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (parameters.Length == 2) { if (double.TryParse(parameters[1], out dataSize)) { Transmit requestTransmit = new Transmit() { SourceID = transmit.SourceID, TargetID = transmit.TargetID, DataType = DataType.Request, Parameter = "Client;AddSocket" }; byte[] buffer = BytesConvert.ObjectToBytes(requestTransmit); if (!Forward(requestTransmit, buffer, buffer.Length)) { return; } Thread.Sleep(3000); List <Socket> sockets = clientCollection.GetClientSockets(transmit.TargetID); targetPort = ((IPEndPoint)sockets[sockets.Count - 1].RemoteEndPoint).Port; if (!Forward(transmit, dataBuffer, readBytes, targetPort)) { return; } continue; } } } CloseClientPort(clientID, clientIPEndPoint.Port); return; } receiveBytes += readBytes; //已接收到的数据累加 //判断已接收到的数据是否有效 if (receiveBytes > 0 && receiveBytes <= dataSize) { if (!Forward(transmit, dataBuffer, readBytes, targetPort)) { break; } } //判断是否接收完成或数据是否有误 if (receiveBytes == dataSize || (receiveBytes <= 0 || receiveBytes > dataSize)) { if (isMain) { ResetParameter(ref isFirstReceive, ref transmit, ref dataSize, ref receiveBytes); continue; } CloseClientPort(clientID, clientIPEndPoint.Port); break; } } }