简体   繁体   English

Cometd/bayeux 客户端问题

[英]Cometd/bayeux client Issue

We have created.Net core windows service for consuming platform events from Salesforce(whenever a particular object created/updated in Salesforce want to fetch the information).We are using Cometd/bayeux client for subscribing Salesforce platforms events.我们已经创建了 .Net 核心 windows 服务,用于从 Salesforce 消费平台事件(每当在 Salesforce 中创建/更新的特定 object 想要获取信息时)。我们正在使用 Cometd/bayeux 客户端订阅 Salesforce 平台事件。

Initially everything working fine we are getting data whenever a change happened in Salesforce object,but after few idle hours(around 1-2 hrs) no data is getting.Check the bayeux client status and it shown as connected but the subscription is not happening.When we restart the service it's started working.最初一切正常,只要 Salesforce object 发生变化,我们就会获取数据,但在空闲几个小时后(大约 1-2 小时)没有数据获取。检查 bayeux 客户端状态,它显示为已连接,但订阅没有发生。当我们重新启动服务时,它就开始工作了。 Using below code for connection and subscription.使用以下代码进行连接和订阅。 Can any one please help on this.任何人都可以帮助解决这个问题。

 public void CheckAndSubscribe()
    {
        if (!_bayeuxClient.IsConnected())
        {
            _logger.LogInformation("Bayeux client not connected. trying to connect...");
            try
            {
                SalesforceSession salesforceSessionData = _sfSessionAdapter.GetSalesforceSession();
                _bayeuxClient.Connect(salesforceSessionData.Url, salesforceSessionData.SessionId);

                List<string> sfChannels = _syncSalesforceConfiguration.BayeuxClientConfiguration.ExternalChannels;

                foreach (string channel in sfChannels)
                {
                    _bayeuxClient.Subscribe(channel, _messageListener);
                }
                _logger.LogInformation("Bayeux client connected and channels subscribed...");
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
            }

        }
    }
 public class BayeuxClientAdapter : IBayeuxClientAdapter
{
    BayeuxClient _bayeuxClient = null;
    private readonly SyncSalesforceConfiguration _syncSalesforceConfiguration;
    public BayeuxClientAdapter(IOptions<SyncSalesforceConfiguration> syncSalesforceConfiguration)
    {
        _syncSalesforceConfiguration = syncSalesforceConfiguration.Value;
    }
    public bool IsConnected()
    {
        return _bayeuxClient?.Connected ?? false;
    }

    public void Connect(string instanceUrl, string authToken)
    {
        int readTimeOut = 120 * 1000;
        string streamingEndpointURI = _syncSalesforceConfiguration.BayeuxClientConfiguration.StreamingEndpointUri;

        IDictionary<string, object> options = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
        {
            { ClientTransport.TIMEOUT_OPTION, readTimeOut },
            { ClientTransport.MAX_NETWORK_DELAY_OPTION, 120000 }
        };

        var headers = new NameValueCollection { { HttpRequestHeader.Authorization.ToString(), $"OAuth {authToken}" } };

        var clientTransport = new LongPollingTransport(options, headers);

        var serverUri = new Uri(instanceUrl);
        String endpoint = String.Format("{0}://{1}{2}", serverUri.Scheme, serverUri.Host, streamingEndpointURI);

        _bayeuxClient = new BayeuxClient(endpoint, new[] { clientTransport });
    }

    public void DisConnect()
    {
        if (IsConnected())
        {
            _bayeuxClient?.ResetSubscriptions();
            _bayeuxClient?.Disconnect();
            _bayeuxClient?.WaitFor(1000, new[] { BayeuxClient.State.DISCONNECTED });
        }
    }

    public void Subscribe(string channel, IMessageListener listener)
    {
        _bayeuxClient.Handshake();
        _bayeuxClient.WaitFor(1000, new[] { BayeuxClient.State.CONNECTED });

        var sfChannel = _bayeuxClient.GetChannel(channel);
        sfChannel.Subscribe(listener);
    }
}

Whenever there is no activity on the channel, the server closes the connection after a specific time.每当通道上没有活动时,服务器会在特定时间后关闭连接。

In that time client receives a 403 (Unknown client) status code, and the client has to handshake again withing 110 seconds.在这段时间内,客户端收到403(未知客户端)状态代码,客户端必须在 110 秒内再次握手。

By default, CometD tries to reconnect without any user interaction and If the client doesn't reconnect within the expected time, the server removes the client's CometD session.默认情况下,CometD 尝试在没有任何用户交互的情况下重新连接,如果客户端未在预期时间内重新连接,服务器将删除客户端的 CometD 会话。

Once the connection gets reconnect, all the channel subscriptions will be removed by ComedD, and we have to subscribe to the channel again in order to receive events.一旦连接重新连接,ComedD 将删除所有频道订阅,我们必须再次订阅频道才能接收事件。

In order to do so, we have to make use of meta/Handshake callback to resubscribe to the channel again.为此,我们必须使用元/握手回调来重新订阅频道。

I found I had to subscribe the meta/unsuccessful event and re-establish the CometD connection and subscriptions.我发现我必须订阅元/不成功事件并重新建立 CometD 连接和订阅。 That allowed the client to recover fully from being disconnected by Salesforce's server.这允许客户端从被 Salesforce 的服务器断开连接后完全恢复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM