.net core SignalR-- real-time push messaging server

background

In the realization native js file upload and display the progress bar in one article, we achieved an Excel upload function, and display real-time progress of the server (正在处理第N行...), so that users do not have Shadeng not know what, this greatly improves the user's experience

There are two ways to achieve this function:

  1. Distal jsto the end of the progress of the service request timer / long polling
  2. websocketBi-direction communication

Choice of two options:

The traditional long polling can achieve real-time news is regularly sent Request message to the server, but the server so the pressure is relatively large, but websocketbased on httpone-way handshake function, do not go back httpup

In the .netmiddle, SignalRto implement a framework for server and client bi-directional communication is websocketa good one package, so I chose it.

Of course, other languages are certainly support websocketcommunication, not limited .net, like nodejsthesocket.io

SignalR

SignalRIt is .neta framework of a server and client bi-directional communication, web-facing side of the chat, SignalRmore simply, of websocketcommunication package

SignalRNo connection limit, depending on the server configuration, the client browser is limited, chrome usually five websocketconnections

What you can do

  • Station live chat, message notifications
  • web page display real-time data
  • Adaptive communication protocol, if the browser or server supports websocket, use websocketthe communication protocol, otherwise downgrade, using long polling服务器一般需要手动开启
  • .net coreCross-platform, version 2.2 has officially builtSignalR

.net coreServer configuration

startupIn ConfigureServices-house method added SignalRservices services.AddSignalR();, Configurein particular configuration Hub(routers, transit):

    app.UseSignalR(routes =>
    {
        routes.MapHub<TestHub>("/testHub");     //可以多个map
    });
    
    app.UseMvc();           //注意UseSignalR需要在UseMvc()之前
复制代码

Such SignalRserver side completed the development, web, Java, .Net client can be connected

Hub message processing center

public class TestHub : Hub
{
    public TestHub()
    {
    }

    public async Task SendMessage(string message, string name)
    {
        #region Client
        //this.Context.ConnectionId                 //每个连接一个connectionId  表示唯一客户端
        //this.Clients.Client().SendAsync();        //指定发送消息
        //this.Clients.Clients()        
        #endregion             //给多个client发消息


        #region Group
        //this.Clients.Group();                     //给某个组发消息
        //this.Clients.Groups()                     //给多个组发消息
        //this.Groups.AddToGroupAsync()             //将指定连接加入组
        //this.Groups.RemoveFromGroupAsync()        //将指定连接移除组 
        #endregion

        await Clients.All.SendAsync("onMsg", DateTime.Now, message);
    }


    //上下线消息  连接、断开事件

    //客户端连接上
    public override Task OnConnectedAsync()
    {
        return base.OnConnectedAsync();
    }

    //客户端断开
    public override Task OnDisconnectedAsync(Exception exception)
    {
        string connectionId = this.Context.ConnectionId;
        return base.OnDisconnectedAsync(exception);
    }
}
复制代码

You can see above SignalRencapsulates many commonly used methods (发送指定消息、群发...), we can achieve a very simple to use

web end of the introduction SignalRof jsa method corresponding to the library, calls the server corresponding to

var connection = new signalR.HubConnectionBuilder().withUrl("/testHub").build();
connection.on("onMsg", function (data, message) {
    console.log(data);
    var li = document.createElement('li');
    li.textContent = `${data}:${message}`;
    document.getElementById("content").appendChild(li);
});

connection.start().then(function () {

}).catch(function (err) {
})

function sendMsg() {
    var msg = document.getElementById('txt').value;
    connection.invoke("SendMessage", msg, "xiaoqiu");
    //connection.stop();
}
复制代码

Open two browser access, the basic effect is shown:

Here, we can do a chat room, of course, need to optimize the place will be more

Controller call SignalR Service

In the constructor injection IHubContext<>can be used directly, very convenient:

    private readonly IHubContext<TestHub> _hubContext;

    public HomeController(IHubContext<TestHub> hubContext)
    {
        _hubContext = hubContext;
    }
    
    public async Task<IActionResult> Notify()
    {
        //拿不到当前Hub的clientId  线程是唯一的
        await _hubContext.Clients.All.SendAsync("onMsg", "from controller msg");
        return Ok();
    }
复制代码

And clients generally do not communicate directly Hub, Controller Hub can do call transfer, do multi-application access, customization, permissions, etc.

The previous article, we try to show the progress of Excel, roughly the following code:

[HttpPost]
public async Task<JsonResult> Import()
{
    var connectionId = Request.Form["connectionId"].ToString(); //拿到当前连接的Id
    var importer = new ExcelImporter();
    //自定义的委托,处理业务的参数
    importer.OnImportingEvent += (sender, arg) =>
    {
        var response = new
        {
            isSuccess = arg.IsSuccess,          //当前数据行是否处理(导入转换)成功
            total = arg.TotalRow,               //当前导入的数据总行数
            rowNumber = arg.RowNumber,          //当前处理的行数
            msg = arg.Msg,                      //处理消息
            time = arg.Time,                    //处理时间
            isComplete = false                  //是否全部处理(转换)完毕
        };
        //推送消息,通知到客户端
        _globalHub.InvokeByIDAsync(connectionId, "importMessage", response);
    };
}

//前端的connection处理,监听对应的方法
connection.on('importMessage',function(notice){
    //根据返回的参数进行相应的逻辑处理展示...
})
复制代码

Here, SignalRthe basic usage has finished presentation, please add!

Guess you like

Origin juejin.im/post/5d17000de51d4556d86c7b00