Sending to Azure Event Hub Error - c#

I'm completely brand new to C#, Microsoft Azure, and basically everything. I'm trying to set up an Azure Event Hub that I can send data to. Right now I'm just following the tutorial that can be found here.
It builds just fine, but I receive the same exception every time. The message is the following: An existing connection was forcibly closed by the remote host. This question has been asked before but never answered.
Just to be sure I'm doing this right I'm attaching pictures with where I obtained the values for the Event Hub Connection String and the Hub Name.
Where I got the Event Hub Connection String from.
This one is within the namespace - not the hub itself.
Where I got the Hub Name from.
The code goes as follows:
private const string EventHubConnectionString = "<Connection String>";
private const string EventHubName = "eventhubtest";
Does the Hub Name have to be simply that or a path? Any ideas or help would be greatly appreciated. Thanks.

#Jamie Penzien, I had been stuck with this exact same error for days and my colleague asked me to change the following part and it worked.
var connectionStringBuilder = new EventHubsConnectionStringBuilder(EventHubConnectionString)
{
EntityPath = EventHubName,
TransportType = TransportType.AmqpWebSockets
};
I am still trying to understand the reason, and it may have something to do with the company's firewall settings.

Eventhub name or Entity Path would be simply the name of EventHub found under an EventHub namespace.
You can use below code to create client:
EventHubClient eventHubClient;
var connectionStringBuilder = new EventHubsConnectionStringBuilder(EventHubConnectionString)
{
EntityPath = EventHubName
};
eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
EventHubsConnectionStringBuilder can be found under Microsoft.Azure.EventHubs package.

I answered my own questions. First, I needed to change the connection string and make sure it contained the entity path within it. Then when establishing the hub client I did this:
eventHubClient = EventHubClient.CreateFromConnectionString(EventHubConnectionString);
HOWEVER, I was getting this exception specifically because of a firewall issue. I have to open ports (working on it right now) to allow outbound communication to the event hub. I believe these are ports 5671 and 5672.
Thank you to all that answered and #RayX who nailed it on the head.

Related

How to connect xamarin android app to Cloud Firestore db

I have tried many ways as in several sites but no luck, I tried to connect it using Google.Cloud.Firestore and Google.Apis.Storage.v1 Nuget packages. The code is given below.
Google.Cloud.Firestore.FirestoreDb db = Google.Cloud.Firestore.FirestoreDb.Create("test");
CollectionReference collection = db.Collection("users");
DocumentReference document = await collection.AddAsync(new { email = "xamemail#12", name = "xamemail" });
When I tried this code one exception occurred like environment variable GOOGLE_APPLICATION_CREDENTIALS not set, then I set GOOGLE_APPLICATION_CREDENTIALS in my windows system as well as in the code as shown below.
System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", #"C:\\path-to-json", EnvironmentVariableTarget.Machine);
It's showing another error the file is not found in the path, but its there and I set the permission for the path.
If anyone there to help on this, anyone already using a xamarin - cloud firestore db in your projects?
Please note its not the firebase realtime db, I am able to connect that.
As far I have understood, you can’t use default credentials (GOOGLE_APPLICATION_CREDENTIALS) in an app on a device as it would not be able to find the path for the file located on your PC.
I have found this code, that I think should work, (But so far, I have not managed to succeed with it - I get an exeption, so I hope my answer can help to inspire someone else to find a solution for this)
using Google.Cloud.Firestore;
using Google.Cloud.Firestore.V1;
using Google.Apis.Auth.OAuth2;
using Grpc.Auth;
using Grpc.Core;
...
//First Pack your Jason fil into a Jason string.
//Fore security reasons I'm not sure this is a good idea, but it is what I could think of
string jsonCred = #”{ Your Json cred file (Replace “ with ‘) }”;
// Get you credential. As far as I have understood it must be scoped.
var credential = GoogleCredential.FromJson(jsonCred).CreateScoped(FirestoreClient.DefaultScopes);
// Create a channel and add the channel to the Firestore client
Channel channel = new Channel(FirestoreClient.DefaultEndpoint.Host, FirestoreClient.DefaultEndpoint.Port, credential.ToChannelCredentials());
FirestoreClient client = FirestoreClient.Create(channel);
// Then I think it should be possible to call.
FirestoreDb db = FirestoreDb.Create(projectId, client);
But so far, I in the line:
FirestoreClient client = FirestoreClient.Create(channel):
I get this exception:
System.TypeLoadException: VTable setup of type Google.Cloud.Firestore.V1.FirestoreClientImpl failed at Google.Cloud.Firestore.V1.FirestoreClient.Create (Grpc.Core.Channel channel, Google.Cloud.Firestore.V1.FirestoreSettings settings) [0x0000c] in T:\src\github\google-cloud-dotnet\releasebuild\apis\Google.Cloud.Firestore.V1\Google.Cloud.Firestore.V1\FirestoreClient.cs:622 at Padlelogg.DataHandler.SaveToFireStore[T] (System.String collection, System.Collections.Generic.List`1[T] Datalist) [0x00072] in C:\Users\rad\Documents\Xamarin projects\Padlelogg 2.10\Padlelogg\Data\DataHandler.cs:360 }
This exception I have not been able to resolve so far

Cannot connect to Azure ServiceBus with Microsoft.Azure.ServiceBus

I have created a very simple console application that connects to Azure ServiceBus and sends one message. I tried the latest library from Microsoft (Microsoft.Azure.ServiceBus) but no matter what I do I just get this error:
No connection could be made because the target machine actively
refused it ErrorCode: ConnectionRefused
I have tried exactly the same connection string in Service Bus Explorer and it does work just fine. Moreover I connected without problems using the older library from Microsoft (WindowsAzure.ServiceBus).
var sender = new MessageSender("endpoint", "topicName");
sender.SendAsync(new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject("test"))));
I tried with .NET Framework 4.6.2 and Core, same exception. I suspect there may be some differences in the default protocol that these libraries use, but I could not figure out that for sure.
P.S. Have tried the example from Microsoft docs but result is still the same exception
The old client supported ConnectivityMode using TCP, HTTP, HTTPS, and AutoDetect. ServiceBus Explorer is using AutoDetect, trying TCP first and then failing over to HTTPS, regardless of the TransportMode you were using (SBMP or AMQP).
With the new client this has changed. TransportMode now combines both options and offers Amqp (AMQP over TCP) or AmqpWebSockets (AMQP over WebSockets). There's no AutoDetect mode. You will have to create your clients and specify TransportType as AmqpWebSockets to bypass blocked TCP port 5671 and instead use port 443.
It seems that the documentation is lacking a lot on how to connect using HTTPS (Amqp over WebSockets) but after some help from Sean Feldman in the accepted answer I managed to connect. Here is the code that I used if someone is interested:
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
"RootManageSharedAccessKey", // SharedAccessKeyName
"SomeToken");
var sender = new MessageSender(
"sb://mydomain.servicebus.windows.net/",
"topicName",
tokenProvider,
TransportType.AmqpWebSockets);
Or a variant that let's you have the whole connection string in one piece
var builder = new ServiceBusConnectionStringBuilder("YouConnectionString");
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
builder.SasKeyName,
builder.SasKey);
var sender = new MessageSender(
builder.Endpoint,
"TopicName",
tokenProvider,
TransportType.AmqpWebSockets);
It is actually possible to use ConnectionString directly but then it has to be augmented to use the right protocol.
var sender = new MessageSender("TransportType=AmqpWebSockets;Endpoint=...", "TopicName")
Or the version that allows to embed EntityPath into the ConnectionString
var connectionBuilder = new ServiceBusConnectionStringBuilder("EntityPath=MyTopic;TransportType=AmqpWebSockets;Endpoint=...")
var sender = new MessageSender(connectionBuilder);
I was having the same issue but his worked for me
var clientOptions = new ServiceBusClientOptions();
clientOptions.TransportType = ServiceBusTransportType.AmqpWebSockets;
client = new ServiceBusClient(connectionString, clientOptions);
sender = client.CreateSender(topicName);
// create a batch
using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

Akka.NET Configuration settings for remoting

I am using the example on the Akka.NET github to play with some basic remoting.
In the remoting example available from GitHub there is the following section in the configuration string for Akka.NET.
deployment {
/localactor {
router = round-robin-pool
nr-of-instances = 5
}
/remoteactor {
router = round-robin-pool
nr-of-instances = 5
remote = ""akka.tcp://system2#localhost:666""
}
}
remote {
dot-netty.tcp {
port = 1234
hostname = localhost
}
What does the forward slash / indicate? is this a comment or is this just the format of the files?
What does the router option 'round-robin-pool' control? I can see that it maps to the following class but I am hoping someone can explain what akka.routing actually means in the context of a remoting scenario? I am assuming this has something to do with how urls or ips are mapped?
Any clarification would be appreciated.
Consider the following snippet from the example:
/localactor {
router = round-robin-pool
nr-of-instances = 5
}
What does the forward slash / indicate? is this a comment or is this just the format of the files?
The forward slash is not a comment; it indicates the name of an actor. The code in the example refers to the actor named localactor in the following way:
var local = system.ActorOf(Props.Create(() => new SomeActor("hello", 123)).WithRouter(FromConfig.Instance), "localactor");
What does the router option 'round-robin-pool' control? I can see that it maps to the following class but I am hoping someone can explain what akka.routing actually means in the context of a remoting scenario? I am assuming this has something to do with how urls or ips are mapped?
round-robin-pool is used to define a router. localactor in the above configuration snippet is a router actor that creates a pool of five routee instances to which it routes messages in round-robin order. A router has no special meaning in a remoting context; it is essentially no different from a router in a non-remoting scenario. You can read more about routers in the linked documentation.

Azure Notification Hub installation not updating tags

I am attempting to update the tags of an installation within Azure Notification Hub after registration. I am following several guides for this, notably here and here.
Both of these guides suggest that the following code should work however it is plainly not; the tag never gets updated. There are no errors, and I can guarantee that the installationId is correct. I am guessing I am setting the path/value of the tag incorrectly.
// in constructor:
var _notificationHub = NotificationHubClient.CreateClientFromConnectionString(Settings.ConnectionStrings.NotificationHub, Settings.Defaults.NotificationHubName);
// in WebApi endpoint:
var installationUpdates = new List<PartialUpdateOperation>();
var userDetail = _userDetailRepo.Get(id);
installationUpdates.Add(new PartialUpdateOperation
{
Operation = UpdateOperationType.Replace,
Path = "/tags/interestedin", // is this incorrect?
Value = interestedIn.ToUpper()
});
userDetail.InterestedIn = interestedIn;
await Task.WhenAll(
_userDetailRepo.InsertOrReplace(userDetail),
_notificationHub.PatchInstallationAsync(installationId, installationUpdates));
Here is the installation object's tags, as per VS:
I also tried hardcoding the path to Path = "/tags/interestedin:W" but it made no difference.
Can someone tell me if I am doing something wrong here, and if so how I should amend my code. Thanks.
Unfortunately, Path = "/tags/interestedin" is not going to work as of now. We are currently working on wildcards' support. Once it is done, something like "/tags/interestedin*" will work fine for you.
While Path = "/tags/interestedin:W" should be OK. If you could provide namespace name, hub name, and a timeframe, then I'll take a look at logs to check what is going on there.

Finding Connection by UserId in SignalR

I have a webpage that uses ajax polling to get stock market updates from the server. I'd like to use SignalR instead, but I'm having trouble understanding how/if it would work.
ok, it's not really stock market updates, but the analogy works.
The SignalR examples I've seen send messages to either the current connection, all connections, or groups. In my example the stock updates happen outside of the current connection, so there's no such thing as the 'current connection'. And a user's account is associated with a few stocks, so sending a stock notification to all connections or to groups doesn't work either. I need to be able to find a connection associated with a certain userId.
Here's a fake code example:
foreach(var stock in StockService.GetStocksWithBigNews())
{
var userIds = UserService.GetUserIdsThatCareAboutStock(stock);
var connections = /* find connections associated with user ids */;
foreach(var connection in connections)
{
connection.Send(...);
}
}
In this question on filtering connections, they mention that I could keep current connections in memory but (1) it's bad for scaling and (2) it's bad for multi node websites. Both of these points are critically important to our current application. That makes me think I'd have to send a message out to all nodes to find users connected to each node >> my brain explodes in confusion.
THE QUESTION
How do I find a connection for a specific user that is scalable? Am I thinking about this the wrong way?
I created a little project last night to learn this also. I used 1.0 alpha and it was Straight forward. I created a Hub and from there on it just worked :)
I my project i have N Compute Units(some servers processing work), when they start up they invoke the ComputeUnitRegister.
await HubProxy.Invoke("ComputeUnitReqisted", _ComputeGuid);
and every time they do something they call
HubProxy.Invoke("Running", _ComputeGuid);
where HubProxy is :
HubConnection Hub = new HubConnection(RoleEnvironment.IsAvailable ?
RoleEnvironment.GetConfigurationSettingValue("SignalREndPoint"):
"http://taskqueue.cloudapp.net/");
IHubProxy HubProxy = Hub.CreateHubProxy("ComputeUnits");
I used RoleEnviroment.IsAvailable because i can now run this as a Azure Role , a Console App or what ever in .NET 4.5. The Hub is placed in a MVC4 Website project and is started like this:
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(50);
RouteTable.Routes.MapHubs();
public class ComputeUnits : Hub
{
public Task Running(Guid MyGuid)
{
return Clients.Group(MyGuid.ToString()).ComputeUnitHeartBeat(MyGuid,
DateTime.UtcNow.ToEpochMilliseconds());
}
public Task ComputeUnitReqister(Guid MyGuid)
{
Groups.Add(Context.ConnectionId, "ComputeUnits").Wait();
return Clients.Others.ComputeUnitCameOnline(new { Guid = MyGuid,
HeartBeat = DateTime.UtcNow.ToEpochMilliseconds() });
}
public void SubscribeToHeartBeats(Guid MyGuid)
{
Groups.Add(Context.ConnectionId, MyGuid.ToString());
}
}
My clients are Javascript clients, that have methods for(let me know if you need to see the code for this also). But basicly they listhen for the ComputeUnitCameOnline and when its run they call on the server SubscribeToHeartBeats. This means that whenever the server compute unit is doing some work it will call Running, which will trigger a ComputeUnitHeartBeat on javascript clients.
I hope you can use this to see how Groups and Connections can be used. And last, its also scaled out over multiply azure roles by adding a few lines of code:
GlobalHost.HubPipeline.EnableAutoRejoiningGroups();
GlobalHost.DependencyResolver.UseServiceBus(
serviceBusConnectionString,
2,
3,
GetRoleInstanceNumber(),
topicPathPrefix /* the prefix applied to the name of each topic used */
);
You can get the connection string on the servicebus on azure, remember the Provider=SharedSecret. But when adding the nuget packaged the connectionstring syntax is also pasted into your web.config.
2 is how many topics to split it about. Topics can contain 1Gb of data, so depending on performance you can increase it.
3 is the number of nodes to split it out on. I used 3 because i have 2 Azure Instances, and my localhost. You can get the RoleNumber like this (note that i hard coded my localhost to 2).
private static int GetRoleInstanceNumber()
{
if (!RoleEnvironment.IsAvailable)
return 2;
var roleInstanceId = RoleEnvironment.CurrentRoleInstance.Id;
var li1 = roleInstanceId.LastIndexOf(".");
var li2 = roleInstanceId.LastIndexOf("_");
var roleInstanceNo = roleInstanceId.Substring(Math.Max(li1, li2) + 1);
return Int32.Parse(roleInstanceNo);
}
You can see it all live at : http://taskqueue.cloudapp.net/#/compute-units
When using SignalR, after a client has connected to the server they are served up a Connection ID (this is essential to providing real time communication). Yes this is stored in memory but SignalR also can be used in multi-node environments. You can use the Redis or even Sql Server backplane (more to come) for example. So long story short, we take care of your scale-out scenarios for you via backplanes/service bus' without you having to worry about it.

Categories