You want to set up real-time
connections between users of your .NET MAUI app, or maybe even your Web app and all
kinds of platforms. Check out this video on how to get started with
SignalR and .NET MAUI. So for those of you who are
unfamiliar, what SignalR exactly is? It is a framework that has been created by
Microsoft and more specifically, the ASP.NET team, which is a layer on top of
WebSockets and I think a couple of other
technologies as well, which allow you to create real time connections between servers
and clients and other clients. And you can do all kinds of amazing
stuff with it. So think of like you're collaborating with
someone on a document in Microsoft Word. You can collaborate together
these days that could be very well powered. I don't know
exactly if it is. Maybe that could be very well powered by a Signal our
connection. Same thing for like a simple chat application, right,
where you see the chat messages popping up. You could definitely do
that with a SignalR connection. Or like my good friend Shaun who has
been creating a .NET MAUI game with air hockey, and he
makes sure that the paddles are in sync. And
because you're doing multiplayer, it's in sync and that's being kept in
sync with SignalR. So that is really cool. Now,
SignalR works based on Hubs. So you're going to connect to
a Hub which can be hosted in a ASP.NET application. So
you can create your own web server application. Or there is an
Azure service that can do that for you as well, which makes
it even easier to set this up. But I want you to know what's
going on under the hood. So we're going to create that ASP.NET
Core web hosting application ourselves first. But feel
free to leave down in the comments whenever something is not clear about
SignalR. This ASP.NET thing, maybe you want to
see the SignalR service in Azure. Let me know down in the comments and
I'll make a video on that. But for now, let's just hop into
Visual Studio and see what this is all about. All right, so here we hopped
into my screen share and you can see I put up Visual Studio 2022 and I
created a File, New .NET MAUI application. The .NET
MAUI application hasn't changed one bit yet, but I did add a
little ASP.NET Core project to the solution yet. So you can see that
right here in our Solution Explorer. And I added some code in that already
so that you don't have to watch this lengthy video, do all the things.
But again, if you want to know in more detail how I set up the server
and what it all exactly is, please let me know down in the
comments. I'll walk you through it very quickly. So what you want to do, actually
SignalR, the package is already in there, by default. So you don't need
to do anything for that. You want to go to the Program.cs. And here in this
builder I added a couple of comments which are
marked with Gerald so you can see what has been going on.
We want to enable the SignalR functionality and you can just say
builder. So that's the generic code builder that we now also know in
.NET MAUI, Builder.Services.AddSignalR() and boom, the functionality is enabled
but you need to do this to enable it. Now if we scroll down a little bit,
you will see here another Gerald comment and I moved this line. This line is
actually here down on line 23 typically or 24 somewhere around
there, but outside of this if, which makes sure that you do the
use HTTPS redirection, which is something that
you totally want to use, you want to use HTTPS. But if you're
developing locally with your .NET MAUI application, this
might cause some issues. So I've set this to if is development or not if it's development. So
whenever you're running in production then this is definitely still going to happen.
But for our development environment, we are going to skip this for a little
bit. And here I'm doing actually a SignalR thing again where I say
hey App.MapHub. So here is that Hub thing that I
mentioned earlier and we're going to look at that chat hub
object. You want to specify what hub you want to use and you can have
multiple ones for multiple things. And here you have to specify
the endpoint is going to map to. So whenever we are running the server
application you can go to chat so
www.myawesomechatapplication.com/chat and that will be the endpoint
where you can reach this hub and actually invoke functionality. So
that's really cool. Now let's have a look at that ChatHub
here. It's very simple, it inherits from a
Hub which is something that's provided by SignalR. And here we have
this async task SendMessage. Now SendMessage is an
endpoint that we can then reach. So basically it will come down
to probablychat SendMessage, I don't know how it works under the
covers exactly. We don't need to worry about that. We'll see that in a
minute. And here we can specify parameters, we can just put those in here. We can
have multiple parameters. It can be complex objects. SignalR will take
care of the serialization for us, no worries. But in this case
we just have a simple string that we are going to send. We're going to
print that out on the console for the server and we're going to do await
Clients.All. So we're just going to broadcast this to all
clients. You can also make groups of clients and have separate IDs and
things. You can totally do that. But we're
going to broadcast this to all clients and we're going to SendAsync a MessageReceived and a message received. Basically that's
something that you can hook into. It's an event if you will. You can say, hey,
whenever message received. When you're listening to that for your
client, then you want to trigger some logic in your
client, right? And we're going to provide that same message. So basically
whenever a message comes in from one client, we're going to broadcast that to all
the other clients. That's what we're going to see. Now, one other
thing here for the server is inside of our Properties. We have these
launchSettings and you can see here, typically whenever you
start a new project, it says localhost here, but you want to make that 0.0.0.0.
So that it listens on all IP addresses and make
note that you have an HTTPS endpoint and an HTTP
endpoint. You want to use the HTTP endpoint. Probably we'll get into
why in a little bit, but just use that one for
now. Again in your development environment
because you want to use HTTPS whenever you go to production. Now that is our
little server thing. Now let's switch over to our .NET MAUI application. So
like I said, this is just a plain .NET MAUI
application. I didn't change the thing yet. This is just a waving .NET
bot template that you're seeing here. So let's implement some
things. Actually, let's start with the code behind. Well, no, let's start
with the UI. Let's start with the UI. That's easier. So I'm
going to get rid of this image. I'm going to reuse a couple of the
template things right here. Get rid of this image. The label. I don't need
the text, but I'm going to give this a name. And this is
going to be our chat messages. So let's make this chat
messages. And I'm going to remove this little
accessibility thing here because it's not really useful. Let's make the font
size, let's make it 18, a little bit smaller. And the second
label is going to be an entry now because for a chat we need a
label where we are going to see all the chat messages and we're
going to have an entry where we can actually type our own message. So
let's do the entry. Again, don't need a text here, let's
just make this x:Name is myChatMessage. And again, no accessibility stuff
here. We don't really need that. Font size
can be the same. And let's add a little placeholder
here so that we know where we can type our message. Type your message. Okay, there we are. And this button is
going to be our well, let's name this, we don't really need
the name but send button and the text is going to be
Send so that we are going to send our actual
message. Let's remove this accessibility thing. The click is
still going to be OnCounterClicked fine by me. So let's go to the code behind.
So in our Solution Explorer. I'm going to click this MainPage.xaml.cs. We don't need this count anymore and
we're going to replace this body of OnCounterClicked. So let's
remove that. And what we need to do is now actually set up our connection
to that Hub. Now there is, depending on how you
architected your application, different ways and different places
where you want to set up that connection. For now I'm just going to
focus on this one page. You can do this through like dependency
injection, all kinds of services, do all kinds of crazy stuff, but I'm going to
do it here for just this page you can figure out the rest. You're a
smart person, you can do it. So let's see at a couple of things.
Actually the first thing I need to do is right click on our .NET MAUI
project and say Manage NuGet Packages and I want
to install the SignalR client because we are going to use
this NuGet package for our convenience. So we have this
Microsoft.AspNetCore.SignalR.Client latest stable version at the time of recording 6.0.6. So let's
just install that. It will install a couple of other
dependencies as well. Let's click okay, read the agreement here, I accept and
it's going to install that and you get on
our project. And once it's done we can go back here and
we're going to instantiate a new field here
and we're going to say private and we can
make that readonly. I'm going to only access it in the constructor...
HubConnection. So here you can see this is a thing from
SignalR and we can just name this connection, it doesn't
really matter what it is. So I would think that the NuGet package
should be installed right now. We're going to have to import
this using so using Microsoft.AspNetCore.SignalR.Client.
It's going to add that using here at the top and now we boom, we have
this connection that we can use. So let's actually do something with
that here in our main page I'm going to fill that connection with _connection = new ConnectionBuilder. So again there's
this builder pattern that we can use and we can say .WithUrl(). And the URL is something again,
something that's going to be different in production and whatever you're
developing. But this is something that you can look up. So for me it's going to be
HTTP so note: HTTP not HTTPS. That's something that you want to take
care of, 192.168.1.85. And in my case it's going to be 5296.
So if we go back to these launchSettings right
here, you can find the port right here that might be
different whenever you set up a new project for you. So be aware of that. So we want
to do that one. And if you don't know where to find
your IP address, just go here to view and you can open a terminal you
can open another terminal if you want as well on your Windows machine
and you can do ipconfig and it will print out all kinds of
information about your network and you probably want to have like, I
don't know, your ethernet adapter or something. It's going to be here
IPV4 address and that's the IP address that you want to use so
that's how you can find that. So make sure to use that one. And then
we're going to say build. So you have other options here for the
ConnectionHubBuilder, you have all kinds of other methods like
automatic retry and all kinds of other options. We're not going to focus on that right
now. I just want to say this is the URL, build that connection and
we have this connection ready to go. We do need to
connect to it manually and we'll see that next. So the other thing we
want to do, we now know that we have this broadcast that
message that we want to listen to, right? So we have
connection on and with the angle brackets here, we can
specify the parameter types that we expect to put in here. So this was a string
because we only had that string message, right? And then we can say
message receive. So it's a little bit you probably want
to make some constant for this if you're sharing code because this is
now magic strings because this refers to our chat hub here. This is
this message received and we have this one parameter, right, which is
message. And if we would have another thing which is an int, then this is one, two, one
and you could say here comma int. And now we
would expect two parameters, one, the first one
being a string and the second one being an integer, right? So you can make all
kinds of things for that but let's not do that for now. I just want this
message so we have this message received and then
whenever that happens you want to invoke some code. So I'm going to do this
with this lambda expression and I expect this message right here
and invoke it like this you can make a separate method from this
if that's what you want and I'm going to say ChatMessages text plus is I'm just going to append the
message to my chat messages label with a little new line
so that it shows up nicely. So I'm going to say environment
newline so that it works across all platforms and I'm
going to say message. So now it's going to do a new line and
add the message and what I'm going to do is, well I'm not
going to do anything. This is it. So this is
what we're going to print out here and then what we want to do is
actually connect to our hub. So now we've set up this method for whenever
we get a message, whenever we get a ping. And
now we actually want to connect to our hub, right? So because it's an async method, it's always a little bit
hard to do that in the constructor. One of the ways to do it is tas run.
I'm not sure if this is the best method, but it's a method
and we also want to do this on the main thread. And for .NET MAUI
you need to do that now through the Dispatcher.Dispatch and we can trigger a little code here
and we can say await _connection. StartAsync(), there we are. So that's what we want to do. And now our
connection should be up and running as well. So if we run this, we should
actually have messages coming in, but we're not really invoking anything
to actually send messages, right? So let's do that as well. We're going
to do that on the click of our button and I'm going to say await.
So we need to make this async it does that automatically await
_connection. InvokeCoreAsync)_. And what we want to do is SendMessage, right? So
that's the method that we want to invoke and the send
message has to correspond with this send message right here. And
then we want to specify that parameter. So we're going
to say args. So we have these arguments. I think
that's the next parameter right here. So I don't need to specify it,
but you can specify it like this argument. And I'm going to say
new array and this is just going to be a string,
right? So we're going to say my chat message text and now it's going to send that as a parameter and
it's going to invoke that and then it should trigger that
message received and we should see this text come up here as well. What we
also might want to do if we're going to send multiple messages to say
my chat message oh, this is an entry. Yes,
text is string empty so that it resets
automatically and we don't have all that. Now what we want to do
actually this is all we need to do for our functionality. Now
what you want to do is go back to that HTTP endpoint because if
you want to run this on Windows, basically all the platforms,
there has been platform specific ways to kind of like say you
need to now explicitly allow applications to use
HTTP because typically you want to use
HTTPS. So you really have to enable HTTP support basically
for all the apps. I'm going to show you this on Android, so let's me
enable it. For Android, you can also do it for iOS and Windows, but
the process is a little bit different. So for Android you can go to platforms
Android and you go to your AndroidManifest.xml. And here on
the application node, you want to say Android and then Clear... UsesClearTextTraffic. That's the one.
And then you set that to true. And now it's enabled to use HTTP traffic. Now make note of this. Do not enable
this on your production app. You don't want to do
that. But for testing locally, that's definitely what you want to do.
So now we have that in place. And actually
for Windows, I think it works kind of out of the
box. So for Windows, let me just run Windows first we should see
actually it come up and our Windows application and I
actually deployed it to our Android emulator earlier. So
let me just pull that up. And I have here the .NET MAUI SignalR
one. Oh, actually this is not going to
work. I forgot a little step. So the server isn't running right now.
So the Android app is going to crash probably because it's not going
to be able to find the server. And the same thing for the
Windows one because our server isn't running. See it started crashing
because no connection could be made. The machine refused it. And our
Android one is kind of funny that it's still
running. But that should be able to find the server as well.
What you can do is set both the .NET MAUI app and the
server as startup projects. But what I'm going to do
right now is right click on my little project, the server project right
here. And you can go here to debug. And then you can just say start
without debugging. I know that this code works, so I don't need any
debugging here. And then you can see there will be a console window coming up
that's actually going to start a little web application
here. You can see it's listening now on the end points that I have configured. So
this is running, we don't need to worry about that. Now. Let me run the
Windows project again and then it should actually come up. So
let's do that and we can see that whenever we oh, it
actually says 404 not found. That is interesting. I know
what's going on. So I didn't connect here to this chat hub. So you
need to specify the hub name, the endpoint
that you're actually going to connect to the hub. Okay, so let's try again.
I'm going to run this on my Windows machine. See, I make mistakes
too. This is how we learn. And now you've seen me a little bit live
debugging. And if you run into this, what is going on?
So now it connects because it's not crashing. So it apparently connects
and I can just say hello, send that. And it comes here with hello. It shows
that in the label, right? So that's really cool. Now if I start another
instance of this SignalR app, then I can just click this
again and it will start another instance and you can see that I can
actually start chatting with myself. So I can say, here, let me make this a
little bit smaller hello ping and you can see that it comes up
here automatically. Pong and I did the console right line
on the server as well, right? So if we inspect this little
console window right here, you can see the hello and ping pong coming in here as
well. Now let's see if this Android app can connect as
well. And we can actually chat with the three of us
now. So that's really cool. Now we have this ping pong hello from Android. Click me and you can see
hello from Android is popping up as well. Hi there. See? So now we
have this real time connection set up between three ASP.NET
clients. I could easily hook up a web client with JavaScript as
well. And this is how to get started with SignalR. Okay, so a little
struggle because I was not finding, not
connecting to the right endpoint right there. But once that was set up, it was very
easy to do this. Now of course you can add all kinds of
things. You can add authorization because you don't want to just anyone connect to
this endpoint and figure out reverse engineering what is going on here. You
can add all this authorization and make sure that your users are
authorized to actually call these endpoints. You can also
then identify users, chat users. You can create chat
applications with this collaboration software, games with this. You can do
all kinds of crazy stuff. Please let me know down in the
comments if you have any questions or what follow up videos you would like
to see about SignalR and all the goodness that comes with it. Now
if you're interested in .NET MAUI more and you want to follow my channel,
please make sure to like this video so that it spreads to more people. And
there is a lot of other content here as well. Check out this
playlist for all kinds of .NET MAUI goodness. Maybe you want to check out a little
bit about plugins that we have right here. And make sure to click here to
subscribe to my channel. And you will get all of this nice
content on your feed automatically. See you for the next one.
Thanks for sharing! ๐ฅฐ
Great intro to this tech. Thanks! I appreciate you.