I'm taking a look at a Firebase library for .NET:
https://github.com/ziyasal/FireSharp
I have a simple ASP.NET MVC site that I'm using to read/write data to Firebase. It's working great, but I'd like to incorporate the streaming listener functionality so I can get notified when data has changed.
What do I need to do in order to engage that? I don't believe it can just hang off an action method and be notified, correct?
EventStreamResponse response = await _client.OnAsync("chat", (sender, args) => {
System.Console.WriteLine(args.Data);
});
//Call dispose to stop listening for events
response.Dispose();
I figured this out for the most part.
In the Global.asax I have a method like below that I just call on App Start. Strange thing I'm not currently sure why is on initial load it calls the "added" method for all elements in the list.
private static async void EventStreaming()
{
EventStreamResponse response = await FirebaseHelper.Client.OnAsync("emails",
added: (sender, args) =>
{
Debug.WriteLine("ADDED " + args.Data + " -> 2\n");
},
changed: (sender, args) =>
{
Debug.WriteLine("CHANGED " + args.Data);
},
removed: (sender, args) =>
{
Debug.WriteLine("REMOVED " + args.Path);
});
//Call dispose to stop listening for events
//response.Dispose();
}
Try with https://www.nuget.org/packages/FirebaseSharp/ it's a good firebase .Net Client
Related
I have a C# application that connects to a NATS service to send and accept NATS messages. It is working well for some time. However I need to build in some logic that if the NATS service is stopped that I take action in letting the user know that we can't send or receive messages. I looked at examples on the internet and applied it accordingly but when testing I see no response as if the events are not triggered. When I stop the NATS service I am expecting the event to fire and a message to be displayed. Can anyone show me what I am missing?
private void OpenNatsConnections()
{
LocalLog("Opening connection to Nats");
// Setup connection options
Options Opts = ConnectionFactory.GetDefaultOptions();
Opts.Url = appSettings.GetNatsUrl();
Opts.User = appSettings.NATSUsername;
Opts.Password = appSettings.NATSPassword;
Opts.AsyncErrorEventHandler += (sender, args) =>
{
LocalLog("AsyncErrorEventHandler");
};
Opts.ClosedEventHandler += (sender, args) =>
{
LocalLog("ClosedEventHandler");
};
Opts.DisconnectedEventHandler += (sender, args) =>
{
LocalLog("DisconnectedEventHandler");
};
// Open Nats connection, assign event handeler and subscribe to listening channel
try
{
NATSConnection = new ConnectionFactory().CreateConnection(Opts);
AsyncNATSMessageHandler = (sender, args) =>
{
string MessageData = Encoding.ASCII.GetString(args.Message.Data);
DetermineMessageType(MessageData, args.Message.Reply);
};
SubscribeToNATS();
LocalLog("Connected to Nats");
}
catch (Exception e)
{
LocalLog("Critical!! Connection to NATS failed! Error Message - " + e.Message);
}
}
I have managed to resolve the issue. Quite simple rather. I downloaded the latest version of NATS Client and the above code worked and the relevant code is fired when triggered.
I have the follow code section for a web client:
var client = new WebClient();
client.DownloadProgressChanged += (sender, args) =>
client_DownloadProgressChanged(sender, args, this.Context.ConnectionId);
client.DownloadDataCompleted += (sender, evt) =>
{
byte[] result = evt.Result;
aLongRunningTask(result);**
}
My problem is that the "aLongRunningTask" function needs to be initiated upon the completion of the downloaddata method, which is working fine, but since the file I receive is very large, I end up having a string in memory taking up a lot of memory space, that there is no need for since I only need byte[].
evt.Result is sadly a readonly property so I can not empty it, and I can not null the client, since I am running the aLongRunningTask.
Is there any way to either overwrite the evt.Result so it can be cleaned, or another way to get that memory usage emptied.
How about using using
like this
using(var client = new WebClient()){
//your logic
}
This script is the method to subscribe event from Kafka.
using Confluent.Kafka;
using Confluent.Kafka.Serialization;
static void Main(string[] args)
{
string brokerList = "broker";
var topics = new List<string>() { "topicName" };
var config = new Dictionary<string, object>
{
{ "group.id", "ConsumerGroup" },
{ "bootstrap.servers", brokerList },
{ "auto.offset.reset", "earliest" },
{ "enable.auto.commit", false }
};
using (var consumer = new Consumer<string, string>(config, new StringDeserializer(Encoding.UTF8), new StringDeserializer(Encoding.UTF8)))
{
consumer.OnMessage += (obj, msg) =>
{
...
};
consumer.Subscribe(topics);
while (true)
{
consumer.Poll(TimeSpan.FromMilliseconds(1000));
}
}
}
When I trace the code in Debug mode, the order of subscribing event is:
consumer.Subscribe(topics)
consumer.Poll(TimeSpan.FromMilliseconds(1000));
consumer.OnMessage += (obj, msg) =>
Before getting the new event (go to consumer.OnMessage), it spent a little time to poll (in consumer.Poll) and print some information on console window.
As follow:
4|2018-12-12 10:41:53.381|rdkafka#consumer-1|REQTMOUT| [thrd:broker/bootstrap]: broker/bootstrap: Timed out 1 in-flight, 0 retry-queued, 0 out-queue, 0 partially-sent requests
In my original thoughts, it use consumer.Subscribe(topics) to connect broker and use consumer.Poll to consume the new event.
But it seems that the consumer.Poll includes connecting to broker and consuming the new event.
My questions are:
Which function can connect to broker? consumer.Subscribe or
consumer.Poll or?
Why consumer.Poll print the information on console window? And it seems that having some error (Timed out 1 in-flight).
About your first question.
Which function can connect to broker? consumer.Subscribe or consumer.Poll or?
consumer.Subscribe connect to broker and consumer.Poll consume messages.
And about the second one.
Why consumer.Poll print the information on console window? And it seems that having some error (Timed out 1 in-flight).
Confluent.Kafka has released in a new major version in here. If you have any problem with previous versions you can use the recommended version. based on the GitHub repository:
It has more features, is considerably improved and is more performant than 0.11.x releases
I'm trying to set up a specific scenario but, obviously, I'm having problems. My server is a site that primarily hosts a WCF service but I want to add an XSockets host there as well. I have the standard code in the bootstrap code file as per the instructions in the readme.txt. Upon a client connection, I am starting a worker thread which is basically a heartbeat that the client will monitor. The relevant code from the controller is as follows:
public class HeartbeatController : XSocketController
{
public void AddMessage(string message)
{
this.SendToAll(message, "addMessage");
}
}
Within my worker thread I am calling this:
string message = String.Format("pump", Math.Round(cpuCounter.NextValue());
ClientPool connection = ClientPool.GetInstance("ws://mywebsite:4502/HeartbeatController", "*");
connection.Send(message, "addMessage");
Currently I'm testing this with a console client which looks like this:
class Program
{
static XSocketClient socketClient;
static void Main(string[] args)
{
Console.WriteLine("Starting client...");
string url = "ws://mywebsite:4502/HeartbeatController";
socketClient = new XSocketClient(url, "*");
socketClient.OnOpen += socketClient_OnOpen;
socketClient.Open();
while (true)
{
// let it sit and display the "pump" messages
string input = Console.ReadLine();
if (input.Equals("Q", StringComparison.Ordinal))
{
break;
}
}
}
static void socketClient_OnOpen(object sender, EventArgs e)
{
Console.WriteLine("socketClient Opened");
socketClient.Bind("addMessage", OnAddMessage);
}
private static void OnAddMessage(ITextArgs textArgs)
{
Console.WriteLine("AddMessage :: {0}", textArgs.data);
}
}
On the client, if I put a breakpoint in the socketClient_OnOpen method it gets hit so I think it is connecting. But the pump message never makes it to the client.
Two Questions:
Is there anything obvious that I'm missing?
(Unrelated) Since many enterprises really don't like punching holes in their firewalls, is there any way to use port 80 with this setup (so that the client connection would look like "ws://mywebsite/HeartbeatController")?
Thanks for any help!
So to see what your pump actually was sending in to the server I added a custom pipeline.
public class MyPipeline : XSocketPipeline
{
//Incomming textmessage
public override void OnMessage(IXSocketController controller, ITextArgs e)
{
Console.WriteLine("IN " + e.data);
//Let the message continue into the server
base.OnMessage(controller, e);
}
//Outgoing textmessage
public override ITextArgs OnSend(IXSocketProtocol protocol, ITextArgs e)
{
Console.WriteLine("OUT " + e.data);
return base.OnSend(protocol, e);
}
}
Since I then saw that you was sending in a string that actually did not have a property named "message". The actionmethod "AddMessage" expects you to pass in a property message of type string. So you can solve this in two ways, both of them are simple.
Just replace the string parameter in the AddMessage with ITextArgs
public void AddMessage(ITextArgs message)
or...
Pass in a object from your worker thread instead of a string like this
connection.Send(new {message}, "addMessage");
So all you need to do to get it to work is to change this row
connection.Send(message, "addMessage");
with this row
connection.Send(new {message}, "addMessage");
EDIT: Btw, 4.0 is on the way and the client will be very much improved as well as the serverside stuff.
Signalr is usually used in "server" side asp.net through hubs and connections. What I'm trying to accomplish (if possible) is using signalr as a "client" in a website.
I have 2 websites, one as a server and another as a client.
I tried this
public void Start()
{
new Task(this.Listen).Start();
//new Thread(this.Listen).Start();
}
private async void Listen()
{
try
{
using (var hubConnection = new HubConnection("http://localhost:8081"))
{
var myHub = hubConnection.CreateHubProxy("mediaHub");
hubConnection.StateChanged += change => System.Diagnostics.Debug.WriteLine(change.OldState + " => " + change.NewState);
myHub.On<string>(
"log",
message =>
System.Diagnostics.Debug.WriteLine(message + " Notified !"));
await hubConnection.Start();
}
}
catch (Exception exc)
{
// ...
}
}
The server is calling the client like this:
var hub = GlobalHost.ConnectionManager.GetHubContext<MediaHub>() ;
hub.Clients.All.log("Server: " + message);
Nothing reaches the client !
As soon as your connection is ready, you actually dispose it, so it does not stay around. As a quick test, remove the using stuff and make your hubConnection a static member of your class, and check if you get called. If you do, then from there you can refine it, but at least you have clearer what's going on.