задний план
существуетНативный js реализует загрузку файлов и отображает индикатор выполнения.В этой статье мы реализовали функцию загрузки Excel и отображали ход обработки сервера в реальном времени.(正在处理第N行...), вам не нужно заставлять пользователя тупо ждать, не зная, что происходит, что значительно улучшает взаимодействие с пользователем.
Существует два способа реализации такой функции:
- внешний интерфейс
jsПерейти к регулярному запросу сервера для обработки прогресса/длительного опроса -
websocketдвусторонняя связь
Выбор из двух вариантов:
Традиционный долгий опрос также позволяет получать сообщения в реальном времени, то есть регулярно отправлять запросы на сервер для получения сообщений, но это создает большую нагрузку на сервер иwebsocketна основеhttpВыполните функцию рукопожатия, а затем не уходитеhttpохватывать
существует.netсередина,SignalRФреймворк, используемый для реализации двусторонней связи между сервером и клиентом, долженwebsocketОчень хороший пакет, поэтому я выбрал его.
Конечно, другие языки точно поддерживаютсяwebsocketобщение, не ограничиваясь.net,рисунокnodejsизsocket.io
SignalR
SignalRда.netФреймворк для двусторонней связи между сервером и клиентом в веб-ориентированном обмене мгновенными сообщениями,SignalRпроще, даwebsocketсвязь инкапсулирована
SignalRОграничения на подключение нет, зависит от конфигурации сервера, у браузерного клиента есть ограничение, у хрома вообще 5websocketсоединять
что можно сделать
- Внутренний чат в режиме реального времени, уведомление о сообщениях
- Отображение данных в реальном времени на веб-страницах
- Адаптивный протокол связи, если он поддерживается браузером или сервером.
websocket, просто используйтеwebsocketПротокол связи, в противном случае понижение версии, использование длительного опроса服务器一般需要手动开启 -
.net coreКроссплатформенный, официально встроен в версию 2.2.SignalR
.net coreКонфигурация сервера
startupсерединаConfigureServicesдобавить внутренний методSignalRСлужитьservices.AddSignalR();,Configureнастроить конкретныеHub(маршрутизатор, транзит):
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub"); //可以多个map
});
app.UseMvc(); //注意UseSignalR需要在UseMvc()之前
такSignalRРазработка на стороне сервера завершена, и можно подключить веб-страницы, клиенты Java и .Net.
Центр обработки сообщений Hub
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);
}
}
Как видно вышеSignalRИнкапсулирует многие распространенные методы(发送指定消息、群发...), мы можем использовать его очень просто для достижения цели
Представлено из ИнтернетаSignalRизjsСоответствующая библиотека классов, вызовите соответствующий метод на стороне сервера
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();
}
Откройте два браузера для доступа, основной эффект будет следующим:
На данный момент мы можем полностью сделать чат, Конечно, будет больше мест для оптимизации.
Вызов службы SignalR в контроллере
Внедрить в конструкторIHubContext<>Его можно использовать напрямую, очень удобно:
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();
}
Как правило, хаб не взаимодействует с клиентом напрямую, хаб можно вызвать в контроллере для передачи, доступа к нескольким приложениям, пользовательских функций, разрешений и т. д.
В предыдущей статье мы показывали ход пробной обработки Excel, примерный код такой:
[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){
//根据返回的参数进行相应的逻辑处理展示...
})
сюда,SignalRБазовое использование было введено, добро пожаловать в добавление!