Continue Learning
I've been using ASP. SignalR (below SignalR Core) to provide websocket support for small programs, the front end time also sent a learning note, in the process of using a little bit of its source code, I have to say that Microsoft is really powerful now, A lot of things to think about, such as using Redis, after using Redis, your websocket support scale-out, and the way to use is also very simple, just need to services.AddSignalR add the following:
.AddRedis(options =>
{
options.Configuration.ConnectTimeout = 30;
options.Configuration.EndPoints.Add("redis ip");
})
SignalR Core leverages Redis's publish-subscribe feature to scale out, without worrying about a single WS server.
Today is not about SIGNALR Core's load balancing approach, but how to gracefully invoke the front-end approach. We all know that signalr core in addition to the establishment of WebSocket connection, can also be called bidirectional, the server calls the client method, the client can also invoke the server method.
Original call
Let's look at how to invoke the client method:
Public class ChatHub : Hub
{
//server method
Public async Task SendMessage(string user, string message)
{
//ReceiveMessage is a client method that lets all clients call this method
Await Clients.All.SendAsync("sayHello", user, message);
}
}
or chathub~~~~~
We can see here we call the client's SayHello, and passed a string of two parameters user,message, is not feel ugly, said the real really look down ha. and constant maintenance, the equivalent of you have to hard code method name, pass the number of parameters is not a quasi, no good document later difficult to maintain. Fortunately, Microsoft has for us to consider this situation, we can use the method of the client interface to define the Method!!! Right! Yes, the method of defining the client in the way of interface!!
Graceful invocation
The way to use is also super simple, we first define a client interface:
public interface IMyClient
{
Task SayHello(string user, string message);
}
Then our hub integrated hub, T is your definition of the client interface, here is imyclient, I use the above Chathub example:
Public class SendMessageHub : Hub<IMyClient>
{
Public async Task SendMessage(string user, string message)
{
Await this.Clients.All.SayHello(user, "from server:" + message);
//ReceiveMessage is a client method that lets all clients call this method
//await Clients.All.SendAsync("sayHello", user, message);
}
}
Commented out is my previous way, SayHello is the client's method, will pass through the websocket to the front end, for me to use the small program communication produces the result:
Isn't it soeasy?? I think it is not finished, our parameters are now in accordance with the way the array is passed, if there is a qualified parameter name is perfect, we modified the next imyclient:
public interface IMyClient
{
Task SayHello(HelloMessage message);
}
public class HelloMessage
{
public string User { get; set; }
public string Message { get; set; }
}
To modify the SendMessage method of our hub:
public Task SendMessage(string user, string message)
{
return this.Clients.All.SayHello(new HelloMessage()
{
User = user,
Message = "from server:" + message
});
//return this.Clients.All.SendAsync("sayHello", $"from server:{message}");
}
Under Run our applet:
Look, the method name does not change, but the parameter we return is an object, if you read my previous post, I should remember that in the front end, I need to do a mapping to invoke the front-end method, in the map, my parameters are used to pass the array, Now you don't need to see the first few parameters in the array I need to use, you can use it completely:
console.log(methods, args);
let self = this;
let arg = args[0];
switch (methods) {
case 'SayHello':
self.sayHello(arg.message);
break;
}
},
Here is another problem, that is, the method name in the interface is the beginning of the uppercase, and the specification of JS is generally lowercase beginning, so in the mapping method need to pay attention to, anyway, this case is not very cool, the parameters in the transfer is directly converted to the first letter lowercase, I believe SIGNALR Core can be achieved, but I do not know, later in the study, if feasible, I will update this blog post. If you want to use lowercase in the interface to define this method, there is no problem, but I think it is not conform to the norms, the habit does not allow me so rough, haha.
Written in the last
As for the principle of the call, I did not look closely, just in the source of the time, see the Hub, very confused, try to find signalr after the next, found that it is really SIGNALR 2.1 quoted this concept, estimated that many people are already in use, but it seems that few people mentioned, Including Microsoft's documentation, this is also an accidental discovery, quickly recorded, hoping to be useful to you.
The ASP. NET Core signalr is really powerful, interested can go to Gayhub to study their source code.