/// <summary> 心跳包\在线客户端线程 /// </summary> public static void _HeartBeatThread() { while (true) { if (LoginFlag) { int minute = DateTime.Now.Minute; if (minute % 5 == 0 && (minute > 4 || minute == 0)) { //服务站在线状态 ContolHandler.UpLoadServerStatus(); DateTime currentTime = GlobalStaticObj_Server.Instance.CurrentDateTime; foreach (string dbName in _dbList) { //在线用户 ContolHandler.UpLoadOnline(dbName, GlobalStaticObj_Server.Instance.UserUploadTime.ToString()); } //备份上传时间 GlobalStaticObj_Server.Instance.LastUploadTime = currentTime.Ticks.ToString(); //写入 ConfigManager.SaveConfig(ConfigConst.UserUploadTime, GlobalStaticObj_Server.Instance.UserUploadTime, ConfigConst.ConfigPath); } HeartBeatHandler.SendHeartBeat(); } //心跳包间隔 Thread.Sleep(waitSecond * 1000); } }
public static void Switch(QRServer server, EndPoint endPoint, byte[] recv) { try { switch (recv[0]) { case QRClient.Avaliable: AvailableCheckHandler.BackendAvaliabilityResponse(server, endPoint, recv); break; // Note: BattleSpy make use of this despite not being used in both OpenSpy and the SDK. // Perhaps it was present on an older version of GameSpy SDK case QRGameServer.Challenge: ChallengeHandler.ServerChallengeResponse(server, endPoint, recv); break; case QRClient.Heartbeat: // HEARTBEAT HeartBeatHandler.HeartbeatResponse(server, endPoint, recv); break; case QRClient.KeepAlive: KeepAliveHandler.KeepAliveResponse(server, endPoint, recv); break; default: server.UnknownDataRecived(recv); break; } } catch (Exception e) { LogWriter.Log.WriteException(e); server.ReceiveAsync(); } }
/// <summary> /// Callback method for when the UDP Query Report socket recieves a connection /// </summary> protected override void ProcessAccept(UDPPacket packet) { IPEndPoint remote = (IPEndPoint)packet.AsyncEventArgs.RemoteEndPoint; // Need at least 5 bytes if (packet.BytesRecieved.Length < 5) { Release(packet.AsyncEventArgs); return; } // If we dont reply, we must manually release the EventArgs back to the pool Replied = false; try { switch (packet.BytesRecieved[0]) { case QRClient.Avaliable: AvaliableCheckHandler.BackendAvaliabilityResponse(this, packet); break; // Note: BattleSpy make use of this despite not being used in both OpenSpy and the SDK. // Perhaps it was present on an older version of GameSpy SDK case QRGameServer.Challenge: ChallengeHandler.ServerChallengeResponse(this, packet); break; case QRClient.Heartbeat: // HEARTBEAT HeartBeatHandler.HeartbeatResponse(this, packet); break; case QRClient.KeepAlive: KeepAliveHandler.KeepAliveResponse(this, packet); break; default: LogWriter.Log.Write("[QR] [Recv] unknown data: ", LogLevel.Error); break; } } catch (Exception e) { LogWriter.Log.WriteException(e); } finally { //if we replied QR data we release packet so that the EventArgs can be used on another connection if (Replied == true) { Release(packet.AsyncEventArgs); } } }
public void Init() { m_net = new NetManager(); m_net.Init(typeof(KCPConnection), (int)ConnID.ZoneServer, 0); m_net.RegisterRPCListener(this); GlobalEvent.onUpdate.AddListener(OnUpdate); ConsoleInput.onInputKey.AddListener(OnInputKey); m_heartbeat = new HeartBeatHandler(); m_heartbeat.Init(m_net); m_heartbeat.onTimeout.AddListener(OnHeartBeatTimeout); }
/// <summary> 心跳包\在线客户端线程 /// </summary> public static void _HeartBeatThread() { while (true) { //foreach (string dbName in dbList) //{ // //上传在线客户端 // ContolHandler.UpLoadData(dbName); //} if (LoginFlag) { HeartBeatHandler.SendHeartBeat(); } //心跳包间隔 Thread.Sleep(waitSecond * 1000); } }
/// <summary> 心跳包\在线客户端线程 /// </summary> public static void _HeartBeatThread() { try { var min = 0; while (true) { if (LoginFlag) { int minute = DateTime.Now.Minute; if (minute % 5 == 0 && (minute > 4 || minute == 0)) { FactoryHandler.HandleLocalFacData(); //服务站在线状态 ContolHandler.UpLoadServerStatus(); DateTime currentTime = GlobalStaticObj_Server.Instance.CurrentDateTime; foreach (string dbName in _dbList) { //在线用户 ContolHandler.UpLoadOnline(dbName, GlobalStaticObj_Server.Instance.UserUploadTime.ToString()); } //备份上传时间 GlobalStaticObj_Server.Instance.LastUploadTime = currentTime.Ticks.ToString(); //写入 ConfigManager.SaveConfig(ConfigConst.UserUploadTime, GlobalStaticObj_Server.Instance.UserUploadTime, ConfigConst.ConfigPath); } //if (min != minute) //{ HeartBeatHandler.SendHeartBeat(); min = minute; //} } //心跳包间隔 Thread.Sleep(waitSecond * 1000); } } catch (Exception ex) { GlobalStaticObj_Server.CloudPadLogService.WriteLog("云平台", ex); } }
/// <summary> /// Argument Constructor /// </summary> /// <param name="configFile">Name of the configuration file to read</param> /// <param name="heartbeatThreshold">Duration to wait for the expected heartbeat before disconnecting</param> /// <param name="heartbeatResponseInterval">Timer after which server will send Heartbeat to connecting Applications</param> public MqServer(string configFile, int heartbeatThreshold, int heartbeatResponseInterval) { // Initialize Disruptor _dataDisruptor = new Disruptor.Dsl.Disruptor <RabbitMqRequestMessage>(() => new RabbitMqRequestMessage(), _ringSize, TaskScheduler.Default); // Add Consumer _dataDisruptor.HandleEventsWith(this); // Start Disruptor _dataRingBuffer = _dataDisruptor.Start(); _configFile = configFile; _heartBeatHandler = new HeartBeatHandler(heartbeatThreshold, heartbeatResponseInterval); _heartBeatHandler.ApplicationDisconnect += OnApplicationDisconnect; _heartBeatHandler.ResponseHeartbeat += OnResponseHeartbeat; //initialize zmqcontext InitializeZmq(); }
private void Listen(SslStream sslStream) { while (!isShutdown) { //Read the message into a proto message Thread.Sleep(1); byte[] _length = new byte[sizeof(int)]; int readBytes = 0; do { Thread.Sleep(0); readBytes += sslStream.Read(_length, readBytes, _length.Length - readBytes); } while (readBytes < _length.Length); int length = BitConverter.ToInt32(_length.Reverse().ToArray(), 0); if (length <= 0) { continue; } if (length > MaxMessageSize) { string exceptionMsg = "Message length " + length.ToString() + " is out of range (0 - " + MaxMessageSize.ToString() + ")"; throw new System.IndexOutOfRangeException(); } byte[] _message = new byte[length]; readBytes = 0; do { Thread.Sleep(0); readBytes += sslStream.Read(_message, readBytes, _message.Length - readBytes); } while (readBytes < length); var msgFactory = new OpenApiMessagesFactory(); var protoMessage = msgFactory.GetMessage(_message); //recieved a msg so show View connection is still alive HeartBeatHandler?.Invoke(); if (protoMessage.PayloadType > 49 && protoMessage.PayloadType < 54) { switch ((ProtoPayloadType)protoMessage.PayloadType) { case ProtoPayloadType.ERROR_RES: ErrorHandler?.Invoke(protoMessage.ToString()); break; case ProtoPayloadType.HEARTBEAT_EVENT: //heartbeat Event HeartBeatHandler?.Invoke(); break; case ProtoPayloadType.PING_REQ: MessageHandler?.Invoke("Ping req"); break; case ProtoPayloadType.PING_RES: MessageHandler?.Invoke("Ping res"); break; } } else { //check what the message type is and perform the relevant operations switch ((ProtoOAPayloadType)protoMessage.PayloadType) { case ProtoOAPayloadType.PROTO_OA_ERROR_RES: //an error has been received var error = ProtoOAErrorRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); ErrorHandler?.Invoke("Proto message error " + error.ErrorCode + " " + error.Description); break; case ProtoOAPayloadType.PROTO_OA_ORDER_ERROR_EVENT: //an error with an order has been found var orderError = ProtoOAOrderErrorEvent.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); OnTradeFail?.Invoke(orderError.CtidTraderAccountId, "Trade Failed: " + orderError.ErrorCode + " " + orderError.Description); break; case ProtoOAPayloadType.PROTO_OA_EXECUTION_EVENT: var executionEvent = ProtoOAExecutionEvent.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); if (executionEvent.ExecutionType == ProtoOAExecutionType.ORDER_ACCEPTED) { if (executionEvent.Order.OrderType == ProtoOAOrderType.MARKET) { if (executionEvent.Order.ClosingOrder) { OnOrderAccepted?.Invoke(executionEvent.Order.ClientOrderId, executionEvent.Order.PositionId, true); } else { OnOrderAccepted?.Invoke(executionEvent.Order.ClientOrderId, executionEvent.Order.PositionId, false); } } else if (executionEvent.Order.OrderType == ProtoOAOrderType.STOP_LOSS_TAKE_PROFIT) { OnStopTargetAccepted?.Invoke(executionEvent.Order.ClientOrderId, executionEvent.Order.PositionId); } } else if (executionEvent.ExecutionType == ProtoOAExecutionType.ORDER_FILLED) { if (executionEvent.Order.ClosingOrder) { OnOrderFilled?.Invoke(executionEvent.Order.ClientOrderId, executionEvent.Order.PositionId, executionEvent.Order.ExecutedVolume, true); } else { OnOrderFilled?.Invoke(executionEvent.Order.ClientOrderId, executionEvent.Order.PositionId, executionEvent.Order.ExecutedVolume, false); } } else if (executionEvent.ExecutionType == ProtoOAExecutionType.ORDER_CANCELLED) { OnOrderCancelled?.Invoke(executionEvent.Order.ClientOrderId, executionEvent.Order.PositionId); } break; case ProtoOAPayloadType.PROTO_OA_ACCOUNT_AUTH_RES: //auth has been recieved for the account var auth = ProtoOAAccountAuthRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); OnAccountAuthorised?.Invoke(auth.CtidTraderAccountId); break; case ProtoOAPayloadType.PROTO_OA_APPLICATION_AUTH_RES: //Application has been authorised so continue the connection to get account and symbol data MessageHandler?.Invoke("App authorised."); BeginConnection(); break; case ProtoOAPayloadType.PROTO_OA_SYMBOLS_LIST_RES: //When requesting the list of all available assets var symbols = ProtoOASymbolsListRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); MessageHandler?.Invoke("Symbols downloaded for account " + symbols.CtidTraderAccountId); //get the associated user UserConfig config = Users.Where(x => x.Value.AccountId == symbols.CtidTraderAccountId).Select(x => x.Value).FirstOrDefault(); //store the symbols in a dictionary where the key is the id foreach (ProtoOALightSymbol symbol in symbols.SymbolList) { config.Symbols.Add(new Symbol((int)symbol.SymbolId, symbol.SymbolName)); } //Save to file so they can be easily reloaded on program restart try { config.SaveToFile(); } catch (IOException ex) //non critical so just flag an error { ErrorHandler?.Invoke("Could not save symbols list for account id " + symbols.CtidTraderAccountId + ": " + ex.Message); } //start subscribing to tick events StartSubscribes(symbols.CtidTraderAccountId); break; case ProtoOAPayloadType.PROTO_OA_SPOT_EVENT: //Tick has been recieved var details = ProtoOASpotEvent.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); //record the time of the tick in UTC time (the tick time doesn't actually come with the payload) DateTime tickTime = DateTime.UtcNow; //get the associated user UserConfig config_spot = Users.Where(x => x.Value.AccountId == details.CtidTraderAccountId).Select(x => x.Value).FirstOrDefault(); //Queue this for writing to file - queue as TickData class which also has the time at which the tick was recieved if (details.HasBid) { if (ShouldWriteTicks) { _ticksToWrite[config_spot.Token].Enqueue(new TickData((int)details.SymbolId, tickTime, true, details.Bid)); } //Notify a tick has been recieved SymbolTickHandler?.Invoke(config_spot, details.SymbolId, true, details.Bid, tickTime); } if (details.HasAsk) { if (ShouldWriteTicks) { _ticksToWrite[config_spot.Token].Enqueue(new TickData((int)details.SymbolId, tickTime, false, details.Ask)); } //Notify a tick has been recieved SymbolTickHandler?.Invoke(config_spot, details.SymbolId, false, details.Ask, tickTime); } break; case ProtoOAPayloadType.PROTO_OA_GET_ACCOUNTS_BY_ACCESS_TOKEN_RES: var accounts_list = ProtoOAGetAccountListByAccessTokenRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); //get the first account - we only need 1 account to extract tick data - no trading will take place ProtoOACtidTraderAccount account = accounts_list.CtidTraderAccountList.FirstOrDefault(); //assign the account id that will be used to extract ticks (Users are stored as a dictionary with token as the key) if (account != null) { Users[accounts_list.AccessToken].AccountId = (long)account.CtidTraderAccountId; } else { throw new MissingFieldException("There are no trading accounts associated with this token."); } MessageHandler?.Invoke("Account selected: " + account.CtidTraderAccountId); //Save to file so it can be easily reloaded on program restart try { Config.SaveToFile(); } catch (IOException ex) //non critical so just flag an error { ErrorHandler?.Invoke("Could not save config file with updated account id: " + ex.Message); } //get the symbols available to this account AuthAccount(accounts_list.AccessToken); break; case ProtoOAPayloadType.PROTO_OA_SUBSCRIBE_SPOTS_RES: var spotRes = ProtoOASubscribeSpotsRes.CreateBuilder().MergeFrom(protoMessage.Payload).Build(); break; default: ErrorHandler?.Invoke((ProtoOAPayloadType)protoMessage.PayloadType + " message not handled."); break; } ; } } }