private void OnSnapshot(BitfinexWebSocketWrapper webSocket, int channelId, string[][] entries) { try { Channel channel; lock (_locker) { BitfinexWebSocketChannels channels; if (!_channelsByWebSocket.TryGetValue(webSocket, out channels)) { return; } if (!channels.TryGetValue(channelId, out channel)) { _brokerage.OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}")); return; } } switch (channel.Name.ToLowerInvariant()) { case "book": ProcessOrderBookSnapshot(channel, entries); return; } } catch (Exception e) { Log.Error(e); throw; } }
private void OnUnsubscribe(BitfinexWebSocketWrapper webSocket, Messages.ChannelUnsubscribing data) { try { lock (_locker) { List <BitfinexChannel> channels; if (!_channelsByWebSocket.TryGetValue(webSocket, out channels)) { return; } channels.Remove(channels.First(x => x.ChannelId == data.ChannelId)); if (channels.Count != 0) { return; } _channelsByWebSocket.TryRemove(webSocket, out channels); } webSocket.Close(); webSocket.ConnectionHandler.DisposeSafely(); } catch (Exception e) { Log.Error(e); throw; } }
private void OnSubscribe(BitfinexWebSocketWrapper webSocket, ChannelSubscription data) { try { lock (_locker) { var channel = new Channel(data.Channel, _symbolMapper.GetLeanSymbol(data.Symbol, SecurityType.Crypto, Market.Bitfinex)); BitfinexWebSocketChannels channels; if (!_channelsByWebSocket.TryGetValue(webSocket, out channels)) { _onSubscribeEvent.Set(); return; } channels.TryAdd(data.ChannelId, channel); Log.Trace($"BitfinexSubscriptionManager.OnSubscribe(): Channel subscribed: Id:{data.ChannelId} {channel.Symbol}/{channel.Name}"); _onSubscribeEvent.Set(); webSocket.ConnectionHandler.EnableMonitoring(true); } } catch (Exception e) { Log.Error(e); throw; } }
private void OnReconnectRequested(object sender, EventArgs e) { var connectionHandler = (DefaultConnectionHandler)sender; Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): WebSocket reconnection requested [Id: {connectionHandler.ConnectionId}]"); BitfinexWebSocketWrapper webSocket = null; lock (_locker) { webSocket = _channelsByWebSocket.Keys .FirstOrDefault(connection => connection.ConnectionId == connectionHandler.ConnectionId); } if (webSocket == null) { Log.Error($"BitfinexSubscriptionManager.OnReconnectRequested(): WebSocket ConnectionId not found: {connectionHandler.ConnectionId}"); return; } Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): IsOpen:{webSocket.IsOpen} [Id: {connectionHandler.ConnectionId}]"); if (!webSocket.IsOpen) { Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Websocket connecting. [Id: {connectionHandler.ConnectionId}]"); webSocket.Connect(); } if (!webSocket.IsOpen) { Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Websocket not open: IsOpen:{webSocket.IsOpen} [Id: {connectionHandler.ConnectionId}]"); return; } Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Reconnected: IsOpen:{webSocket.IsOpen} [Id: {connectionHandler.ConnectionId}]"); BitfinexWebSocketChannels channels; lock (_locker) { if (!_channelsByWebSocket.TryGetValue(webSocket, out channels)) { return; } } Log.Trace($"BitfinexSubscriptionManager.OnReconnectRequested(): Resubscribing channels. [Id: {connectionHandler.ConnectionId}]"); foreach (var channel in channels.Values) { webSocket.Send(JsonConvert.SerializeObject(new { @event = "subscribe", channel = channel.Name, pair = _symbolMapper.GetBrokerageSymbol(channel.Symbol) })); } }
private BitfinexWebSocketWrapper GetFreeWebSocket(BitfinexChannel channel) { int count; lock (_locker) { foreach (var kvp in _channelsByWebSocket) { if (kvp.Value.Count < MaximumSubscriptionsPerSocket) { kvp.Value.Add(channel); count = _channelsByWebSocket.Sum(x => x.Value.Count); Log.Trace($"BitfinexSubscriptionManager.GetFreeWebSocket(): Channel added: Total channels:{count}"); return(kvp.Key); } } } if (!_connectionRateLimiter.WaitToProceed(TimeSpan.Zero)) { _connectionRateLimiter.WaitToProceed(); } var webSocket = new BitfinexWebSocketWrapper( new DefaultConnectionHandler { MaximumIdleTimeSpan = TimeSpan.FromSeconds(15) }); lock (_locker) { _channelsByWebSocket.TryAdd(webSocket, new List <BitfinexChannel> { channel }); count = _channelsByWebSocket.Sum(x => x.Value.Count); Log.Trace($"BitfinexSubscriptionManager.GetFreeWebSocket(): Channel added: Total channels:{count}"); } webSocket.Initialize(_wssUrl); webSocket.Message += OnMessage; webSocket.Error += OnError; Connect(webSocket); webSocket.ConnectionHandler.ConnectionLost += OnConnectionLost; webSocket.ConnectionHandler.ConnectionRestored += OnConnectionRestored; webSocket.ConnectionHandler.ReconnectRequested += OnReconnectRequested; webSocket.ConnectionHandler.Initialize(webSocket.ConnectionId); Log.Trace("BitfinexSubscriptionManager.GetFreeWebSocket(): New websocket added: " + $"Hashcode: {webSocket.GetHashCode()}, " + $"WebSocket connections: {_channelsByWebSocket.Count}"); return(webSocket); }
private void OnUnsubscribe(BitfinexWebSocketWrapper webSocket, Messages.ChannelUnsubscribing data) { try { lock (_locker) { Channel channel; if (!_channels.TryRemove(data.ChannelId, out channel)) { return; } _onUnsubscribeEvent.Set(); List <Channel> channels; if (!_channelsByWebSocket.TryGetValue(webSocket, out channels)) { return; } channels.Remove(channel); if (channels.Count(c => c.Symbol.Equals(channel.Symbol)) == 0) { List <BitfinexWebSocketWrapper> subscriptions; if (_subscriptionsBySymbol.TryGetValue(channel.Symbol, out subscriptions)) { subscriptions.Remove(webSocket); if (subscriptions.Count == 0) { _subscriptionsBySymbol.TryRemove(channel.Symbol, out subscriptions); } } } if (channels.Count != 0) { return; } _channelsByWebSocket.TryRemove(webSocket, out channels); } webSocket.Close(); webSocket.ConnectionHandler.DisposeSafely(); } catch (Exception e) { Log.Error(e); throw; } }
private BitfinexWebSocketWrapper GetFreeWebSocket(Channel channel) { lock (_locker) { foreach (var kvp in _channelsByWebSocket) { if (kvp.Value.Count < MaximumSubscriptionsPerSocket) { return(kvp.Key); } } } if (!_connectionRateLimiter.WaitToProceed(TimeSpan.Zero)) { _connectionRateLimiter.WaitToProceed(); } var webSocket = new BitfinexWebSocketWrapper( new DefaultConnectionHandler { MaximumIdleTimeSpan = TimeSpan.FromSeconds(15) }); lock (_locker) { _channelsByWebSocket.TryAdd(webSocket, new BitfinexWebSocketChannels()); } webSocket.Initialize(_wssUrl); webSocket.Message += OnMessage; Connect(webSocket); webSocket.ConnectionHandler.ReconnectRequested += OnReconnectRequested; webSocket.ConnectionHandler.Initialize(webSocket.ConnectionId); int connections; lock (_locker) { connections = _channelsByWebSocket.Count; } Log.Trace("BitfinexSubscriptionManager.GetFreeWebSocket(): New websocket added: " + $"Hashcode: {webSocket.GetHashCode()}, " + $"WebSocket connections: {connections}"); return(webSocket); }
private void OnSubscribe(BitfinexWebSocketWrapper webSocket, Messages.ChannelSubscription data) { try { lock (_locker) { var channel = new Channel(data.Channel, _symbolMapper.GetLeanSymbol(data.Symbol)); _channels.AddOrUpdate(data.ChannelId, channel); _onSubscribeEvent.Set(); webSocket.ConnectionHandler.EnableMonitoring(true); } } catch (Exception e) { Log.Error(e); throw; } }
private void OnUpdate(BitfinexWebSocketWrapper webSocket, string channelId, string[] entries) { try { BitfinexChannel channel; lock (_locker) { List <BitfinexChannel> channels; if (!_channelsByWebSocket.TryGetValue(webSocket, out channels)) { _brokerage.OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}")); return; } channel = channels.FirstOrDefault(x => x.ChannelId == channelId); if (channel == null) { _brokerage.OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, $"Message received from unknown channel Id {channelId}")); return; } } switch (channel.Name.ToLowerInvariant()) { case "book": ProcessOrderBookUpdate(channel, entries); return; case "trades": ProcessTradeUpdate(channel, entries); return; } } catch (Exception e) { Log.Error(e); throw; } }
private void OnSubscribe(BitfinexWebSocketWrapper webSocket, Messages.ChannelSubscription data) { try { lock (_locker) { List <BitfinexChannel> channels; if (_channelsByWebSocket.TryGetValue(webSocket, out channels)) { var channel = channels.First(x => x.Name == data.Channel && x.Symbol == data.Symbol); channel.ChannelId = data.ChannelId; webSocket.ConnectionHandler.EnableMonitoring(true); } } } catch (Exception e) { Log.Error(e); throw; } }