I would like to use a c# language server client to connect and communicate with a language server. The language server client I found is here (https://github.com/OmniSharp/csharp-language-server-protocol). In the examples I found code to create a client.
protected virtual ILanguageClient CreateClient(Action<LanguageClientOptions> clientOptionsAction = null)
{
_client = LanguageClient.Create(
options => {
var (reader, writer) = SetupServer();
options
.WithInput(reader)
.WithOutput(writer)
.WithLoggerFactory(TestOptions.ClientLoggerFactory)
.WithAssemblies(TestOptions.Assemblies)
.WithAssemblies(typeof(LanguageProtocolTestBase).Assembly, GetType().Assembly)
.ConfigureLogging(x => x.SetMinimumLevel(LogLevel.Trace))
.WithInputScheduler(options.InputScheduler)
.WithOutputScheduler(options.OutputScheduler)
.WithDefaultScheduler(options.DefaultScheduler)
.Services
.AddTransient(typeof(IPipelineBehavior<,>), typeof(SettlePipeline<,>))
.AddSingleton(Events as IRequestSettler);
clientOptionsAction?.Invoke(options);
}
);
Disposable.Add(_client);
return _client;
}
But it is not clear to me how I can establish a connection to a language server (that is, to a language-server.exe). I found this example here (https://gist.github.com/tintoy/a2ec9424d17fe9ef17db0621479a7b43) but I think it's never has been working or with a very old version of the omnisharp language server client. But in general this is what I want to do. May be someone can give me a working example that can do the same thing like the example just mentioned.
Best regards,
Basti
I found the solution myself. With this example you can request code completion.
ILanguageClient _client;
ProcessStartInfo info = new ProcessStartInfo();
var programPath = #"path\to\language-server.exe";
info.FileName = programPath;
info.WorkingDirectory = Path.GetDirectoryName(programPath);
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process process = new Process
{
StartInfo = info
};
process.Start();
_client = LanguageClient.Create(
options =>
{
.WithInput(process.StandardOutput.BaseStream)
.WithOutput(process.StandardInput.BaseStream)
.WithCapability(
new CompletionCapability
{
CompletionItem = new CompletionItemCapabilityOptions
{
DeprecatedSupport = true,
DocumentationFormat = new Container<MarkupKind>(MarkupKind.Markdown, MarkupKind.PlainText),
PreselectSupport = true,
SnippetSupport = true,
TagSupport = new CompletionItemTagSupportCapabilityOptions
{
ValueSet = new[] { CompletionItemTag.Deprecated }
},
CommitCharactersSupport = true
}
}
);
}
);
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
await _client.Initialize(cancellationTokenSource.Token);
try
{
var actualCompletions = await _client.TextDocument.RequestCompletion(
new CompletionParams
{
TextDocument = #"path\to\someScript.py",
Position = (23, 11),
}, cancellationTokenSource.Token
);
System.Threading.Thread.Sleep(1000);
var items = actualCompletions.Items;
Console.WriteLine("items.Count: {0}", items?.Count());
Console.WriteLine("actualCompletions: {0}", string.Join(",", items?.Select(p => p.Label)));
}
catch (Exception ex)
{
Console.WriteLine("Exception thrown: {0}", ex.Message);
}
Related
Following this example I have now therefore been required to update the MQTT.NET from version 3 (that works thanks the provided help) to version 4.
A very basic set of capabilities would be enough:
Connect to an adress with a timeout
Check if the connection has gone well
Receive messages
check disconnection
that was extremely easy in version 3
MqttClientOptionsBuilder builder = new MqttClientOptionsBuilder()
.WithClientId("IoApp" + HelperN.MQTT.GetClientID(true))
.WithTcpServer("localhost", 1883);
ManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(60))
.WithClientOptions(builder.Build())
.Build();
mqttClient = new MqttFactory().CreateManagedMqttClient();
mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnConnected);
mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnDisconnected);
mqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate(OnConnectingFailed);
mqttClient.SubscribeAsync(...);
mqttClient.SubscribeAsync(...);
mqttClient.StartAsync(options).GetAwaiter().GetResult();
mqttClient.UseApplicationMessageReceivedHandler(args => { OnMessageReceived(args); });
but when it comes to version 4 if I have to relay on those examples I have problems.
Let's start from the connection
public static async Task Connect_Client_Timeout()
{
/*
* This sample creates a simple MQTT client and connects to an invalid broker using a timeout.
*
* This is a modified version of the sample _Connect_Client_! See other sample for more details.
*/
var mqttFactory = new MqttFactory();
strError = String.Empty;
using (var mqttClient = mqttFactory.CreateMqttClient())
{
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("aaaa127.0.0.1",1883).Build();
try
{
using (var timeoutToken = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
await mqttClient.ConnectAsync(mqttClientOptions, timeoutToken.Token);
}
}
catch (OperationCanceledException exc)
{
strError = "Connect_Client_Timeout exc:" + exc.Message;
}
}
}
And I call this task from the main awaiting the result.
var connectTask = Connect_Client_Timeout();
connectTask.Wait();<-----never ends
Since I put a wrong address "aaaa127.0.0.1" I expect a failure after 5 seconds. But the connectTask.Wait never end. But even if I put the right address "127.0.0.1" it never exits.
So perhaps the error stands in the connectTask.Wait();.
Thanks
The solution is here
In short you have to do this:
static async Task Connect()
{
IManagedMqttClient _mqttClient = new MqttFactory().CreateManagedMqttClient();
// Create client options object
MqttClientOptionsBuilder builder = new MqttClientOptionsBuilder()
.WithClientId("behroozbc")
.WithTcpServer("localhost");
ManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(60))
.WithClientOptions(builder.Build())
.Build();
// Set up handlers
_mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync;
_mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync;
_mqttClient.ConnectingFailedAsync += _mqttClient_ConnectingFailedAsync;
// Connect to the broker
await _mqttClient.StartAsync(options);
// Send a new message to the broker every second
while (true)
{
string json = JsonSerializer.Serialize(new { message = "Hi Mqtt", sent = DateTime.UtcNow });
await _mqttClient.EnqueueAsync("behroozbc.ir/topic/json", json);
await Task.Delay(TimeSpan.FromSeconds(1));
}
Task _mqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
{
Console.WriteLine("Connected");
return Task.CompletedTask;
};
Task _mqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
{
Console.WriteLine("Disconnected");
return Task.CompletedTask;
};
Task _mqttClient_ConnectingFailedAsync(ConnectingFailedEventArgs arg)
{
Console.WriteLine("Connection failed check network or broker!");
return Task.CompletedTask;
}
}
and then just call Connect() and rely on the subscribed examples
I've got an Alexa app that on first launch looks for the user's id in a dynamoDB. If it isn't there I'd like it to ask the user for their ip address.
I have an intent that can collect the IP but I was wondering if I could trigger the intent from the launch request?
private SkillResponse LaunchRequestHandler(SkillRequest input, ILambdaContext context)
{
// Initialise response
var skillResponse = new SkillResponse
{
Version = "1.0",
Response = new ResponseBody()
};
// Output speech
SsmlOutputSpeech ssmlResponse = new SsmlOutputSpeech();
try
{
try
{
var strUserId = input.Session.User.UserId;
var request = new GetItemRequest
{
TableName = tableName,
Key = new Dictionary<string, AttributeValue>() { { "strUserId", new AttributeValue { S = strUserId } } },
};
var response = client.GetItemAsync(request);
// Check the response.
var result = response.Result;
var attributeMap = result.Item;
if (result.Item.Count() < 1)
{
ssmlResponse.Ssml = "<speak></speak>";
// Trigger intent to get IP address and port number.
}
else
{
ssmlResponse.Ssml = "<speak>Hi there. I'm not Cortana.</speak>";
// Give command guidance prompt.
}
}
catch (AmazonDynamoDBException e) { ssmlResponse.Ssml = "<speak>" + e.InnerException.Message + "</speak>"; }
catch (AmazonServiceException e) { ssmlResponse.Ssml = "<speak>" + e.Message + "</speak>"; }
catch (Exception e) { ssmlResponse.Ssml = "<speak>" + e.Message + "</speak>"; }
skillResponse.Response.OutputSpeech = ssmlResponse;
skillResponse.Response.ShouldEndSession = true;
}
catch
{
//ssmlResponse.Ssml = "<speak><audio src='/samples/ImSorryDave'/></speak>";
ssmlResponse.Ssml = "<speak>I'm sorry Dave. I'm afraid I can't do that.</speak>";
skillResponse.Response.OutputSpeech = ssmlResponse;
}
skillResponse.Response.ShouldEndSession = true;
return skillResponse;
}
Two options I can think of:
Have you tried just asking for the IP address? <speak> Hi there. What is your IP address?</speak> If you make sure your IP address intent has examples of how you might expect a user to respond to that question, that intent should be the triggered and sent to your skill to process.
Also look into how Alexa can handle some of the dialog management for you with intent chaining. The example there sounds very similar to your use case.
I am trying to connect tls enabled dgraph server using c# .net for that I have written below console application
class DGraphClient
{
public IDgraphClient GetDgraphClient()
{
GraphSchemaIOConnection ConnectionConfig1 = new GraphSchemaIOConnection();
ConnectionConfig1.Endpoint = "testdgraph.abc.tech:9080";
DgraphInstance GSioDgraph = new DgraphInstance();
DgraphCertificates certificates = new DgraphCertificates();
certificates.CaCert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURVekNDQWp1Z0F3SUJBZ0lJR1dnMnhpbzVMYVl3RFFZSktvWklodmNOQVFFTEJRQXdSakVhTUJnR0ExVUUKQ2hNUlJHZHlZWEJvSUV4aFluTXNJRWx1WXk0eEZ6QVZCZ05WQkFNVERrUm5jbUZ3YUNCU2IyOTBJRU5CTVE4dwpEUVlEVlFRRkV3WXhPVFk0TXpZd0hoY05NakV3TWpJeU1EWXpORFU0V2hjTk16RXdNakl5TURZek5EVTRXakJHCk1Sb3dHQVlEVlFRS0V4RkVaM0poY0dnZ1RHRmljeXdnU1c1akxqRVhNQlVHQTFVRUF4TU9SR2R5WVhCb0lGSnYKYjNRZ1EwRXhEekFOQmdOVkJBVVRCakU1Tmpnek5qQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQwpBUW9DZ2dFQkFNeTV4RHN4eXhoTVpUM01TMGplcS9qOGFMM2tCZHZWcmNSS2lTUjY5MFZ1L2xKREk1Zm5tdHduCjN2WWxNbXQyNEVmQ0x4Rzk2S3dqZ3ZVZlBNZFI3WGM2RFFlUWpmanA1TXBaV2VwMzdxWTVURExLcC9YNEF0WUIKcU5reVlQSFo4R1BYOVN1Zk9jSk5vdUZtWStpeDY5L2VkTlpMczA5SC93STd4dDlpREExTzBQVVQ1Z00yZi9vLwp5d2Rpb2J0S3dpNmszY2VxTTRPZ2dLUE92d0k2K0ViOE9TM0wwZ3VIQ05IaHJxM3VjblJKeE5yaWZvNnNoTEhECkdXQ3BRbXRWZDM0azVsY3dVakdBa2k2VTJONU9Yc09TRmozbU1MTnNnaThUeFFWYWlSQzFhNjRqamJKUGVDb0kKNkduamgvb3cwMFpIa05seFBqZWI4Umx5ZzM2RkJEc0NBd0VBQWFORk1FTXdEZ1lEVlIwUEFRSC9CQVFEQWdMawpNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUF3SFFZRFZSME9CQllFRk5HUlQxdkZJSTNiZnBQYk5LcnpnQXBEClJJcGlNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFBWGQ5VXRaYk54Ny8wbjNXMnNVcG9GVVRJTGlsRkc3d0sKY1pMamtxZyt0dXJ5SFd1YVcvcW5NRC9oSTRGeW1lb211Y0hzclhVUVBiLzVTVEl1NkczQWp0U3pxL2o2OVkvQgp4M2RvdGdibStLME9aYmJKRGpwcU1CZnFqSFJCSm1sL0VGcTZ1ME56eGxYd3ZWRDU5SFF6OThpWFZZTzBDYmFnClN4OFFpbUVTWjJ4Mk5vdkZ1c3JHNHhickRaKzlDa1ZvN25OeWliMGZETm4vaXhvZDBRNmVod1d4aXNYV1cxblIKbFd4SzR6aUsxNzNyS1lqQVBaVUxmNEFLR0h5R1pxeU9xaG9EVEczelU4Y2hmYmcyUW9ZOHdZSGZVNGpHb3RKMQp6UCsyenhRR1pyQkFhWVdaakw0TUdyd09BeVEzdGRUSjRURWozZHgwL2hOaGEwbHhIZTVVCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K";
certificates.ClientCert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURWVENDQWoyZ0F3SUJBZ0lJS2Y3WjVYVlVIVjh3RFFZSktvWklodmNOQVFFTEJRQXdSakVhTUJnR0ExVUUKQ2hNUlJHZHlZWEJvSUV4aFluTXNJRWx1WXk0eEZ6QVZCZ05WQkFNVERrUm5jbUZ3YUNCU2IyOTBJRU5CTVE4dwpEUVlEVlFRRkV3WXhPVFk0TXpZd0hoY05NakV3TWpJeU1EWXpORFU1V2hjTk1qWXdNakl6TURZek5EVTVXakJGCk1Sb3dHQVlEVlFRS0V4RkVaM0poY0dnZ1RHRmljeXdnU1c1akxqRVdNQlFHQTFVRUF4TU5kbWx6ZFhKeFlXUm4KY21Gd2FERVBNQTBHQTFVRUJSTUdNamxtWldRNU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQgpDZ0tDQVFFQXF1QU04ZnlhY3l2QW42VDF2TTNsRWYrYm9QendRdVlBTW5zaFNmNjFuZVhFVTNlZ3l5cmFLSVg1CjNrSkhIV0JqSGE1T2lNUG1ib3pWT2phUldlZGVXZDdTWmozb0IwV3NEd3YzTHhuN0dPUThHQU5UU3VTMURadFYKczBSMkhIamJUM0I1WHRHeXdNVTFORHkwcTZDNXdVT1NOSk85cWhKOW4wMUwrK3ltT3RYd3JCbUhlaVVhd21vRAp2c21mWFlUREJiUC93V0lYeW5vYkd5N3R6cEtteWRmOHErcm0zd0VKQ3FTNGNEVHlwVU0rdWZIVElPYXZXQWE0CnpyUXZ0Mk11bVRiclJSWlRZUVZmdU9jbkduQ3pSS0hjQ2RJWWdFcTl3Zmx0WjRZQjAydUtYZHY2Tkw5aGJrRXYKUmozNlZUMithaG5CS2FZM1l4d0xOVGNqWWxqeXlRSURBUUFCbzBnd1JqQU9CZ05WSFE4QkFmOEVCQU1DQjRBdwpFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd0l3SHdZRFZSMGpCQmd3Rm9BVTBaRlBXOFVnamR0K2s5czBxdk9BCkNrTkVpbUl3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFrYWprLzNmMUo2bDBVZWZPM0ozNEpYOGszMTM4N1oKY1BZaWt1Z1A3M2wwT3dnc2oxY3VHODh3UXczREdDN3NPNlVQU0lzQ2ZHdXlVVzJmZG1QSFN5V3hxbGFGTnN2Zwo3WithVE92aHBYNGVuYTNUcE9lb0FKdUlXOVRjendLZjdBbWo2VEY1MjNaQWtkOVhhcTZMaVVwR0QzdFdhajgxCmRBK3dRVTgvaE5tZ29GR2lhVmFqYm9wVFU0K0hvTG9HWExuTTY3dU5TdGJEQ05uVlluZExDTHpDM1BORUtEYVAKdC9kMEQvczB6L1lnMi9ZaEFlMzV6WTIzNytFbkZXMCsrbG5wUEtZNFFuY1ozL3ZYN1lhYTlRejZKSFgxOG9oUwpJbVVuUEtsMzlJT21ocEJNckdCK2JxRTRTMFM1eXB3NUl6WUtMLzVsRnVtZVZoSVFoLzVmdHZRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg";
certificates.ClientKey = "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcXVBTThmeWFjeXZBbjZUMXZNM2xFZitib1B6d1F1WUFNbnNoU2Y2MW5lWEVVM2VnCnl5cmFLSVg1M2tKSEhXQmpIYTVPaU1QbWJvelZPamFSV2VkZVdkN1NaajNvQjBXc0R3djNMeG43R09ROEdBTlQKU3VTMURadFZzMFIySEhqYlQzQjVYdEd5d01VMU5EeTBxNkM1d1VPU05KTzlxaEo5bjAxTCsreW1PdFh3ckJtSAplaVVhd21vRHZzbWZYWVREQmJQL3dXSVh5bm9iR3k3dHpwS215ZGY4cStybTN3RUpDcVM0Y0RUeXBVTSt1ZkhUCklPYXZXQWE0enJRdnQyTXVtVGJyUlJaVFlRVmZ1T2NuR25DelJLSGNDZElZZ0VxOXdmbHRaNFlCMDJ1S1hkdjYKTkw5aGJrRXZSajM2VlQyK2FobkJLYVkzWXh3TE5UY2pZbGp5eVFJREFRQUJBb0lCQURmcjYxQ21vc1ZlWkVQYQo4TEZCa040N0VPdTIyOHFKQ3pkNkpJTGE0UVV6MVBTY0NmdHpvc0h3VnIzdVl1ZXlTNzNDOWVDOGZBVmlBY1p6ClpVNU84Z25uYW1RYmpud1N5U1NEZmZua1B0RCtvTXdiQ245UUtoQ3g3WElsemFHenk5Skx0T3piSSswQ25VN2oKTHgyY0ZDNnp0bjJPZkZ2VWdWaEpLN3plemVnaTR4cU1KVm5WY0hucXhnVDIzeW9aQ1Jxcnk5RWpTSjhXUlJuUgpJSWtzZEUrNk9DelJFMmZmekNNTjFKZWREOUlIdlQ0RFBDOVJBdndnR1ZWMjFaTTIzUDM3d3JlS3R6SzEvYkozCmpIOGdmNWFRYVRmM2xndHQ2T2pSY2dPM0xyL094QjFIdGcxa3FGbTJxRktGQVhjcDBEZVp5ZWt4UiszS2NmOFEKc2w0TnQ2RUNnWUVBMWRNdFBmeXF6Z1VYbEt4ZlkyL1dNVWJjVy9JV1ZXczlyN2VkaExEUUJVS3k5Q0R4b3BqTApFNEZKTXhrSngwUGRsUUkxSU5DQ2lZeVZyM3ZhVnQzd3ZmY0FoNFZMTWsvYnhWcFB5NEM3MDZtS1YydUdCZFV1CmFOREVJbkhGUVM2RTJEa0FJNVlNWGdyQVdJU0RwNVc5ZVlvK3hLbW5HdVJTbkZSRlFBZjBiN2NDZ1lFQXpKUXUKZGVwbEV2cE1uQ1VTYnJkQWg4Vkc1bWFPeFJ6aXpZeGNySUNmLzlHa1VZR1ozMjNNcjFIYk1OMS9ycGNRNFNCNgorYlVweHhzaTNQT05uTU9IRUFubTc3R0FTRmZDd2tjSjlFeXZRVXpLOExSd3czbFFtMVRGMDNIR3BLMjNNVEJGCmdKNzBFUkFQUitUK2pIZkFXUm5LdkV3YjcxZFNqZjFGdFZmb3NYOENnWUVBaXRSVTRKVkhkUUliWUYxV2hhSmMKU0p4QWdMWTZ4L1VjRlJXN2dTYW51WEtuN0JmanEzVlhETy81VGVMbzFXYjczRDZWcmh1VFZhbGdtcEpvbmRQMQo5ZkVFZC9rVWJMTXE5d1QvSUJzU1dJZ1FtVmZucWF2VE9SeXE2ODVBaTJTZnZoK3NObTY2MHVoYUlGN1JlQ0toCjVlTGJoQ2ErcDVndEJ2RTBFVEhaQkJzQ2dZQmxxUkU1YVdRV3ZTa0t3dVZZL1ZsazNxU3Y0N0Q0eExUei9kY2oKcGJ0Y2pab0JJczBMR1c0SWhUM09GNVBXZDUxY3NoNUtManQzaE1XYlZMQS9nVzZCaXRvbXJHY2FDL3B0UG8zMAp4NUtqZVh5emhvY3VxLzloWVF2NVdlV2plZXU1MXNvQzgzcEhiRnFibUhEaDdyUTMwcmhMUCtyMTBjZmxaVUdaCnJ2aWtFd0tCZ0QzbjJSNDNHQWZlTnV6V25NZEtDT3BXWTJVQVZHdG5Tbmx2bWhDcHVLM0hnVmV4RGd6d0g1U0YKeG9kNE04U1pBV3lNSGxBcGx2VEFrWE9JWGdHYjgrQVl5aklPVVMybTZocHFlMk1neVZobGZuWFIxeWwrUXJiNwovY0FsN3RpR0kvcmJDZFYvVFpLTVJHN0ZyUVFUK0p2NFErbTlKT0EwNldWMTYrTU5ZNXAwCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg";
GSioDgraph.Certificates = certificates;
GSioDgraph.Address = "testdgraph.abc.tech:9080";
if (ConnectionConfig1.Endpoint.Equals("localhost"))
{
var client = DgraphDotNet.Clients.NewDgraphClient();
client.Connect("");
return client;
}
else
{
var client = DgraphDotNet.Clients.NewDgraphClient();
var caCert = GSioDgraph.Certificates.CaCert;
var clientCert = GSioDgraph.Certificates.ClientCert;
var clientKey = GSioDgraph.Certificates.ClientKey;
var tls = new SslCredentials(caCert, new KeyCertificatePair(clientCert, clientKey));
client.Connect(GSioDgraph.Address, tls);
// var result = client.CheckVersion();
return client;
}
}
and calling check version using below code
DGraphClient dc = new DGraphClient();
try
{
var dgraphClient = dc.GetDgraphClient();
var result1 = await dgraphClient.CheckVersion();
if (result1.IsSuccess)
{
Console.WriteLine("Connected to Dgraph version {Version}", result1.Value);
}
var res = await dgraphClient.Query(query);//.NewTransaction().Query(query);
if (res.IsFailed)
{
Console.WriteLine("ERROR THROWING");
}
result = res.Value;
await dgraphClient.NewTransaction().Commit();
}
catch (Exception ex)
{
throw ex;
}
after instanciate client I am just checking server version to make sure its connected but failed with grpc {Result: IsSuccess='False', Reasons='ExceptionalError with Message='Status(StatusCode=Unavailable, Detail="Empty update")', Exception='Grpc.Core.RpcException: Status(StatusCode=Unavailable, Detail="Empty update")\r\n at DgraphDotNet.GRPCConnection.CheckVersion()\r\n at DgraphDotNet.DgraphClient.CheckVersion()'', }
I'm trying to use Selenium 4 to log requests during manual usage of Chrome browser.
The issue is that request interception stops after around 40 seconds of usage (approximately).
I've tried to change commandTimeout but it didn't change anything.
Also I've tried to look into chromedriver logs but I didn't find anithing there.
Here's my code:
static void Main(string[] args)
{
// Enable chromedriver logging
var service = ChromeDriverService.CreateDefaultService();
service.LogPath = AppDomain.CurrentDomain.BaseDirectory + "chromedriver.log";
service.EnableVerboseLogging = true;
var options = new ChromeOptions();
var webDriver = new ChromeDriver(service, options);
var devToolsSession = webDriver.CreateDevToolsSession();
devToolsSession.Network.Enable(new EnableCommandSettings());
EventHandler<RequestInterceptedEventArgs> requestIntercepted = (sender, e) =>
{
Console.WriteLine(e.Request.Url);
};
RequestPattern requestPattern = new RequestPattern();
requestPattern.InterceptionStage = InterceptionStage.Request;
requestPattern.ResourceType = ResourceType.Image;
var setRequestInterceptionCommandSettings = new SetRequestInterceptionCommandSettings();
setRequestInterceptionCommandSettings.Patterns = new RequestPattern[] { requestPattern };
devToolsSession.Network.SetRequestInterception(setRequestInterceptionCommandSettings);
devToolsSession.Network.RequestIntercepted += requestIntercepted;
while (true)
{
webDriver.Url = "https://translate.google.com/";
Thread.Sleep(5000);
webDriver.Navigate().Refresh();
}
}
As of Selenium 4 beta-1, you can use the Fetch API and retrieve the same resluts (SetRequestIntercepted is deprecated in ChromeTools as late as December 29, 2020).
In either case, the key point for both RequestIntercepted (prior to deprecation) and Fetch to be able to continue after intercepting the request is to capture the RequestId.
With Fetch this can be done in ContinueRequest():
fetch.ContinueRequest(new Fetch.ContinueRequestCommandSettings()
{
RequestId = e.RequestId
});
Below is your code updated to use Fetch which allowed the query to run for 2+ minutes and 5+ minutes before I manually stopped it:
(Note: ensure all of your DevTools as using the same version (i.e. 89 in my case) or you will get errors):
using V89 = OpenQA.Selenium.DevTools.V89;
using V89Net = OpenQA.Selenium.DevTools.V89.Network;
using OpenQA.Selenium.DevTools.V89.Log;
var service = ChromeDriverService.CreateDefaultService();
service.LogPath = AppDomain.CurrentDomain.BaseDirectory + "chromedriver.log";
service.EnableVerboseLogging = true;
var options = new ChromeOptions();
new DriverManager().SetUpDriver(new ChromeConfig(), VersionResolveStrategy.MatchingBrowser);
var driver = new ChromeDriver(service, options);
IDevTools devTools = driver as IDevTools;
var devToolsSession = devTools.GetDevToolsSession();
var fetch = devToolsSession.GetVersionSpecificDomains<V89.DevToolsSessionDomains>()
.Fetch;
var enableCommandSettings = new V89.Fetch.EnableCommandSettings();
var requestPattern = new V89.Fetch.RequestPattern();
requestPattern.RequestStage = V89.Fetch.RequestStage.Response;
requestPattern.ResourceType = V89Net.ResourceType.Document;
enableCommandSettings.Patterns = new V89.Fetch.RequestPattern[] { requestPattern };
fetch.Enable(enableCommandSettings);
void RequestIntercepted(object sender, V89.Fetch.RequestPausedEventArgs e)
{
e.Request.Url.Dump();
fetch.ContinueRequest(new V89.Fetch.ContinueRequestCommandSettings()
{
RequestId = e.RequestId
});
}
fetch.RequestPaused += RequestIntercepted;
while (true)
{
driver.Url = "https://translate.google.com/";
Thread.Sleep(5000);
driver.Navigate().Refresh();
}
Screenshot (From left-to-right): LinqPad output Console.Write.Url equivalent, Above code in LINQPad, and view of Chrome log file)
My team is developing an application that needs to clone existing templates in our vSphere environment. We're using VMware.Vim in a C# application to do this. We're replacing an already existing implementation that uses PowerShell.
Below is the code that is throwing the error. We are eventually going to load balance based on memory usage, but currently we are selecting the host by random. That's why there is some extra code with collecting all of the hosts and then picking one.
When it gets to CloneVM_Task, an exception with the message 'The operation is not allowed in the current state.' is thrown. The exception doesn't give me much to work with and I can't find any useful logs in vSphere. vSphere just says "An error prevented the virtual machine from being cloned" in the events log. We're using version 6.7. I'm new to VMWare, so any help is appreciated. Their documentation is lacking, to say the least.
public async void CreateVirtualMachineAsync(NewVMRequest newVMRequest)
{
var appliance = await _applianceService.GetAppliance(newVMRequest.Appliance);
var vimClient = new VimClientImpl
{
IgnoreServerCertificateErrors = true, ServiceUrl = appliance.ServiceUrl
};
vimClient.Login(appliance.User, appliance.Password);
var datacenter = GetDatacenter(vimClient);
var hostCollection = GetListOfHosts(vimClient, datacenter);
var randomHost = PickRandomHost(hostCollection);
var sourceVm = GetSelectedVm(vimClient, newVMRequest);
if (sourceVm == null)
{
_logger.LogDebug($"Could not find virtual machine {newVMRequest.Source} to use for template");
_logger.LogError($"Could not find virtual machine {newVMRequest.Source} to use for template", null);
return;
}
var selectedStore = ConnectToDataStore(vimClient);
var cluster = GetCluster(vimClient);
var mySpec = CreateCloneSpec(selectedStore, randomHost, cluster, sourceVm);
vimClient.WaitForTask(sourceVm.CloneVM_Task(sourceVm.Parent, newVMRequest.Name, mySpec));
vimClient.Disconnect();
}
private VirtualMachineCloneSpec CreateCloneSpec(Datastore selectedStore, ManagedObjectReference randomHost, ClusterComputeResource cluster, VirtualMachine sourceVm)
{
var mySpec = new VirtualMachineCloneSpec
{
Location = new VirtualMachineRelocateSpec
{
Datastore = selectedStore.MoRef,
Transform = VirtualMachineRelocateTransformation.sparse,
Host = randomHost,
Pool = cluster.ResourcePool
},
Config = new VirtualMachineConfigSpec()
};
var networkDevice = new VirtualDevice();
foreach (var vDevice in sourceVm.Config.Hardware.Device)
{
if (vDevice.DeviceInfo.Label.Contains("Network"))
{
networkDevice = vDevice;
}
}
var devSpec = new VirtualDeviceConfigSpec
{
Device = networkDevice, FileOperation = VirtualDeviceConfigSpecFileOperation.create
};
mySpec.Config.DeviceChange = new[] { devSpec };
return mySpec;
}
private Datacenter GetDatacenter(VimClient vimClient)
{
var entities = vimClient.FindEntityViews(typeof(Datacenter), null, null, null);
return (Datacenter)entities.First();
}
private List<ManagedObjectReference> GetListOfHosts(VimClient vimClient, Datacenter datacenter)
{
var hostCollection = new List<ManagedObjectReference>();
var hostFolderMoRef = datacenter.HostFolder;
var hostFolder = (Folder)vimClient.GetView(hostFolderMoRef, null);
var childEntityMoRefs = hostFolder.ChildEntity;
foreach (var childEntityMoRef in childEntityMoRefs)
{
var thisCluster = (ClusterComputeResource)vimClient.GetView(childEntityMoRef, null);
var clusterHostMoRefs = thisCluster.Host;
foreach (var clusterHostMoRef in clusterHostMoRefs)
{
var hostSystem = (HostSystem)vimClient.GetView(clusterHostMoRef, null);
hostCollection.Add(hostSystem.MoRef);
}
}
return hostCollection;
}
private ManagedObjectReference PickRandomHost(List<ManagedObjectReference> hostCollection)
{
var rand = new Random();
return hostCollection[rand.Next(0, hostCollection.Count)];
}
private VirtualMachine GetSelectedVm(VimClient vimClient, NewVMRequest newVMRequest)
{
var filter = new NameValueCollection
{
{"name", newVMRequest.Source},
{"Config.Template", newVMRequest.UseTemplate.ToString().ToLower()}
};
var entityViews = vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, null);
if (entityViews.Count == 0)
{
return null;
}
return (VirtualMachine)vimClient.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, filter, null).First();
}
private Datastore ConnectToDataStore(VimClient vimClient)
{
var myDs = vimClient.FindEntityView(typeof(Datastore), null, null /*dsFilter*/, null);
return (Datastore)myDs;
}
private ClusterComputeResource GetCluster(VimClient vimClient)
{
var appClusters = vimClient.FindEntityViews(typeof(ClusterComputeResource), null, null, null);
return (ClusterComputeResource)appClusters?.FirstOrDefault();
}
For the most part, your code looks good. I would suggest changing the spec file and using the least possible information to create a clone from existing template. Once you have success, you can add more details and see if that errors out.
Start off with this and see if this gets you going.
private VirtualMachineCloneSpec CreateCloneSpec(Datastore selectedStore, ManagedObjectReference randomHost, ClusterComputeResource cluster, VirtualMachine sourceVm)
{
var mySpec = new VirtualMachineCloneSpec
{
Location = new VirtualMachineRelocateSpec
{
Datastore = selectedStore.MoRef,
Host = randomHost,
Pool = cluster.ResourcePool
},
PowerOn = false,
Template = false
};
return mySpec;
}
If the above goes through, then add the VirtualMachineRelocateTransformation to transform your thick VM as thin VM and network connections as needed.