ServiceStack.Client Server Sent Events are not processed - c#

I have a basic Hello World console program connecting to a web server but none of my callbacks are invoked (nothing gets printed to the console).
using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start ...");
try
{
// http://docs.servicestack.net/csharp-server-events-client
// ServiceSack.Client
var client = new ServerEventsClient("http://localhost:9999/bus/api/v1/subscribe/karli/head/0")
{
OnConnect = connectEvent => Console.WriteLine($"OnMessage {connectEvent}"),
OnCommand = cmd => Console.WriteLine($"OnCommand {cmd}"),
OnMessage = msg => Console.WriteLine($"OnMessage {msg}"),
OnUpdate = upd => Console.WriteLine($"OnUpdate {upd}"),
OnException = err => Console.WriteLine($"OnException {err}")
}.Start();
// keep main thread running ...
var a = Console.Read();
}
catch (Exception ex)
{
Console.WriteLine("dasda {0}", ex);
}
}
private static void OnMessage(ServerEventMessage message)
{
Console.WriteLine($"OnMessage {message}");
}
}
}
while the curl works as expected
$ curl "http://localhost:9999/bus/api/v1/subscribe/karli/head/0/event-stream"
{"key":"1","offset":0,"value":{}}
{"key":"1","offset":1,"value":{}}
{"key":"1","offset":2,"value":{}}
{"key":"1","offset":3,"value":{}}
{"key":"1","offset":4,"value":{}}
{"key":"1","offset":5,"value":{}}
{"key":"1","offset":6,"value":{}}
What am I missing here?

The ServerEventsClient needs to be initialized with the BaseUrl where your ServiceStack Service is located. If you're not hosting ServiceStack at a custom path it would just be host name, e.g:
var client = new ServerEventsClient("http://localhost:9999/") {
///...
}.Start();

Related

c# interprocess communication between .net 6 and framwork 4.8

WCF is really easy to make, literally i think 10 lines you can setup the WCF, but just one problem....i did not work in .net 6, i tried, was happy, until i run the app, he compiles with the exact same code from 4.8 but start generating exception after exception
and after some google, it seams that .net 6 (core) did not support WCF anymore
so what is the best way to make a desktop .net framework 4.8 app and a .net 6 WPF app communicate between then, exchanging some flag and variables
the simplest way possible, preferable one unique way that can be implemented in both 4.8 and 6.0, but i don't mind if is different technologies in both end if it works and is simple
I would prefer Interprocess-Communication via NetNamedPipes (NamedPipeServerStream and NamedPipeClientStream) and using Protobuf serialization.
for people suffering with that, abandon WCF if you just wanna send/get simple flags/infos/strings use NamedPipeServerStream and NamedPipeClientStream as #egal_reloaded posted, some (ugly) code samples:
4.8:
server class:
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PipeTetst_FrameWork48_WCF
{
public class NamedPipeStreamServer
{
public void server()
{
var pipeServer = new NamedPipeServerStream("testpipe481", PipeDirection.InOut, 4);
StreamReader sr = new StreamReader(pipeServer);
StreamWriter sw = new StreamWriter(pipeServer);
do
{
try
{
pipeServer.WaitForConnection();
string test;
sw.WriteLine("Waiting");
sw.Flush();
pipeServer.WaitForPipeDrain();
test = sr.ReadLine();
MessageBox.Show(string.Format("Received from client: {0}", test));
}
catch (Exception ex) { throw ex; }
finally
{
pipeServer.WaitForPipeDrain();
if (pipeServer.IsConnected) { pipeServer.Disconnect(); }
}
} while (true);
}
}
}
client class:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PipeTetst_FrameWork48_WCF
{
public class NamedPipeStreamClient
{
public void client()
{
var pipeClient = new NamedPipeClientStream(".",
"testpipe482", PipeDirection.InOut, PipeOptions.None);
if (pipeClient.IsConnected != true)
{
pipeClient.Connect();
}
StreamReader sr = new StreamReader(pipeClient);
StreamWriter sw = new StreamWriter(pipeClient);
string temp;
temp = sr.ReadLine();
if (temp == "Waiting")
{
try
{
sw.WriteLine("Test Message");
sw.Flush();
pipeClient.Close();
}
catch (Exception ex)
{
throw ex;
}
}
}
}
}
two button on a form in a TASK to not block the app(freeze):
private void button5_Click(object sender, EventArgs e)
{
NamedPipeStreamServer server = new NamedPipeStreamServer();
Task.Run(() => server.server()).ContinueWith(
_ =>
{
MessageBox.Show("asd Server");
}); // Scheduled to the ThreadPool
}
private void button6_Click(object sender, EventArgs e)
{
NamedPipeStreamClient client = new NamedPipeStreamClient();
Task.Run(() => client.client()).ContinueWith(
_ =>
{
MessageBox.Show("asd client");
}); // Scheduled to the ThreadPool
}
and the best part, this code os for .net framwork 4.8 traditional and .net 6 is the exact same code and WORKS!!
of course, you need to have 2 of this code above in 2 app different, and set the name of the pipes right
and the best part NO need to waste days trying to make something broken and unfinished like CoreWCF that need way too much code and is not reliable and only works in some frameworks and in each has a different code, and was almost 0 support they only have a half asset samples on GitHub that don't help with anything

MQTTnet PublishAsync Exception

I'm trying to use "MQTTnet" in a Xamarin application. It connects fine but when I try to publish anything, well, it publishs but after about 5 seconds it throw the following exception
MQTTnet.Exceptions.MqttCommunicationTimedOutException
I'm not quite sure about what's happening there, the message is received successfully by the server
Server auth xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612 from 192.168.1.8
Client xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612 connected
Total connections: 3
$SYS/POezxDu/new/clients xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612
hello/world hey
Client xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612 disconnected
Total connections: 2
$SYS/POezxDu/disconnect/clients xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612
Below is the code:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using System.Threading;
namespace MQTTXamarin
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Login : ContentPage
{
public Login()
{
InitializeComponent();
}
private void Btn_Login_Clicked(object sender, EventArgs e)
{
MqttConnect();
}
/* MQTT */
readonly IMqttClient client = new MqttFactory().CreateMqttClient();
private async void MqttConnect()
{
var options = new MqttClientOptionsBuilder()
.WithClientId("xmr/" + Guid.NewGuid().ToString())
.WithTcpServer("192.168.1.200", 1883)
.WithCredentials("DyPFunIOcljUT51i", "K1YMeKkvrK6yMvm7IlHadBA6JDBKzPGc")
.Build();
await client.ConnectAsync(options, CancellationToken.None);
var message = new MqttApplicationMessageBuilder()
.WithTopic("hello/world")
.WithPayload("hey")
.WithExactlyOnceQoS()
.Build();
await client.PublishAsync(message, CancellationToken.None);
}
}
}
Am I doing something wrong or is this buggy?
This issue was solved changing the
.WithExactlyOnceQoS()
to
.WithAtLeastOnceQoS()

Telegram.bot coding, No error but the simplest commands also does show any results on the prompt

my console application project was working quite good (as a Telegram bot) but today I tried to run the bot again however there was no response from the bot.
then I realised my prompt (visual studio 15 and also 19) shows nothing even the simplest codes like this: AND THERE IS NO ERROR
---------------
"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telegram.Bot;
using Telegram.Bot.Types;
namespace ConsoleApp1
{
class Program
{
static TelegramBotClient Bot = new TelegramBotClient("token here");
static void Main(string[] args)
{
Task.Run(() => RunBot());
Console.ReadKey();
}
public static async Task RunBot()
{
User Robot = await Bot.GetMeAsync();
Console.WriteLine("My username is: {0}", Robot.Username);
Console.WriteLine("------------");
int Ofsset = 0;
while(true)
{
var Updates = await Bot.GetUpdatesAsync(offset: Ofsset);
foreach (var update in Updates)
{
Ofsset = update.Id + 1;
Console.WriteLine("massage from '{0}' Text is: {1}", update.Message.From.Username, update.Message.Text);
}
}
}
}
}
"

Microsoft.Azure.Devices.Common.Exceptions.UnathorizedException

Hi Team I have the following code in C#, i am writting a backend-application using C# to read DeviceToCloudMEssage in Azure portal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.Common;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Azure.Devices;
namespace BackEndApplication
{
class Program
{
private static ServiceClient _serviceClient;
private readonly static string s_connectionString = "HostName=UniversityIOTHub.azure-devices.net;DeviceId=UniversityDeviceIOT;SharedAccessKey=******=";
private static async Task InvokeMethod()
{
var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval") { ResponseTimeout = TimeSpan.FromSeconds(30) };
methodInvocation.SetPayloadJson("10");
var response = await _serviceClient.InvokeDeviceMethodAsync("UniversityDeviceIOT", methodInvocation);
Console.WriteLine("Response status:{0}, payload", response.Status);
Console.WriteLine(response.GetPayloadAsJson());
}
static void Main(string[] args)
{
Console.WriteLine("IOT Hub Test-- BackEndApplication.\n");
_serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString);
InvokeMethod().GetAwaiter().GetResult();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}
}
}
I am getting an authorizedException from the assemblies, one being Microsoft.Azure.Device.Common. The exception hits on InvokeMethod().GetAwaiter().GetResult(). Im also using DeviceExplore to test this exception, payload method i am also getting the same result. Please help me thanks.
What you are doing in your program is not reading DeviceToCloudMessages but invoking a direkt method.
For that you are using the wrong connectionString. The ServiceClient does not connect to your device but to IoT-Hub. So instead of using the IoT-Hub-Device connection string you have to use the IoT-Hub connection string which looks like this:
HostName=<yourIotHub>.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=<yourSharedAccessKey>=
Then you should be able to call _serviceClient.InvokeDeviceMethodAsync. This will make the IoT-Hub trigger the direct method on the device and pass on the response to the calling program.

Why is no message received in WS communication on a UWP device?

I have a WS server and I would like to broadcast messages from that server (using another web app) to all HoloLens devices that are connected to the session.
First I have implemented a MessageWebSocket client in the Hololens app that initiated a connection with a sample public WS server echo.websocket.org just to check if the setup is right on the client side. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if WINDOWS_UWP
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.Web;
using System;
#endif
public class WebSocketClient : MonoBehaviour
{
void Start()
{
#if WINDOWS_UWP
int msgTime = 5;
int fadeTime = 1;
guiPhraseReporter.QueueRaport("START", msgTime, fadeTime);
MessageWebSocket ws = new MessageWebSocket();
ws.Control.MessageType = SocketMessageType.Utf8;
ws.MessageReceived += (MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args) =>
{
guiPhraseReporter.QueueRaport("Trying to receive message...", msgTime, fadeTime);
try
{
using (DataReader dataReader = args.GetDataReader())
{
dataReader.UnicodeEncoding = UnicodeEncoding.Utf8;
string message = dataReader.ReadString(dataReader.UnconsumedBufferLength);
Debug.Log(message);
}
}
catch (Exception ex)
{
Debug.Log("Error occurred");
}
};
ws.Closed += (IWebSocket sender, WebSocketClosedEventArgs args) => {
Debug.Log("WS closed");
};
try
{
Task connectTask = ws.ConnectAsync(new Uri("ws://echo.websocket.org")).AsTask();
connectTask.ContinueWith(async _ =>
{
string message = "Hello, World!";
using (DataWriter dataWriter = new DataWriter(ws.OutputStream))
{
dataWriter.WriteString(message);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
Debug.Log("Sending Hello World");
});
}
catch (Exception ex)
{
WebErrorStatus webErrorStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
// Add additional code here to handle exceptions.
Debug.Log(ex);
}
#endif
}
}
And it works fine, I'm able to send a message to the server, and it is echoed back and received correctly by the client.
Things however mess up when I use the actual server I'll be testing on. On my server, I have replicated the behavior from the echo.websocket.org and I echo back any message sent. I'm able to connect, the connection is not closed (Closed is never called), but I don't receive any messages.
If I test both servers using the web browser (with chrome's Smart Websocket Extension), they both work. The only difference (and only possible lead I got) is that the sample server (the one that works on Hololens) sends more headers upon connection:
vs my server:
Maybe there is some easier way to do this, but so far I didn't find any good WS wrappers that would work on UWP. Any help appreciated.
It was faulty logic on my server app after all. So there was no problem with WS communication to begin with, thank you for your time.

Categories