重构代码:移除WebSockets相关逻辑,使用SignalR
This commit is contained in:
parent
b528810516
commit
26581b6b3b
|
@ -1,5 +1,6 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Linq;
|
||||
|
@ -26,10 +27,10 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public bool Post([FromBody] User user)
|
||||
public bool Post([FromServices]ISignalRHubContext<SignalRHub> hub, [FromBody]User user)
|
||||
{
|
||||
var ret = UserHelper.SaveUser(user);
|
||||
if (ret) NotificationHelper.PushMessage(new MessageBody() { Category = "Users", Message = string.Format("{0}-{1}", user.UserName, user.Description) });
|
||||
if (ret) hub.SendAll(new MessageBody() { Category = "Users", Message = string.Format("{0}-{1}", user.UserName, user.Description) });
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
public class WSController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public IEnumerable<MessageBody> Post()
|
||||
{
|
||||
return NotificationHelper.RetrieveMessages();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ using Longbow.Configuration;
|
|||
using Longbow.Data;
|
||||
using Longbow.Logging;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.WebSockets;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
|
@ -50,6 +50,7 @@ namespace Bootstrap.Admin
|
|||
.SetApplicationName(Configuration["ApplicationName"])
|
||||
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"]));
|
||||
if (Configuration["DisableAutomaticKeyGeneration"] == "True") dataProtectionBuilder.DisableAutomaticKeyGeneration();
|
||||
services.AddSignalRManager();
|
||||
services.AddMvc(options =>
|
||||
{
|
||||
options.Filters.Add<BootstrapAdminAuthorizeFilter>();
|
||||
|
@ -81,8 +82,8 @@ namespace Bootstrap.Admin
|
|||
app.UseStaticFiles();
|
||||
app.UseAuthentication();
|
||||
app.UseBootstrapAdminAuthorization();
|
||||
app.UseWebSocketHandler(options => options.UseAuthentication = true, WSHelper.WebSocketMessageHandler);
|
||||
app.UseCacheManagerCorsHandler();
|
||||
app.UseSignalR(routes => { routes.MapHub("/NotiHub"); });
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
|
|
|
@ -18,11 +18,13 @@
|
|||
<environment include="Development">
|
||||
<script src="~/js/sweetalert.js"></script>
|
||||
<script src="~/js/jquery.mCustomScrollbar.js"></script>
|
||||
<script src="~/js/signalr.js"></script>
|
||||
<script src="~/js/toastr.js"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="~/js/sweetalert.min.js"></script>
|
||||
<script src="~/js/jquery.mCustomScrollbar.concat.min.js"></script>
|
||||
<script src="~/js/signalr.min.js"></script>
|
||||
<script src="~/js/toastr.min.js"></script>
|
||||
</environment>
|
||||
<script src="~/js/jquery.dcjqaccordion.2.7.js"></script>
|
||||
|
|
|
@ -216,25 +216,23 @@ $(function () {
|
|||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
// load widget data
|
||||
$('.header .nav').reloadWidget().socketHandler({
|
||||
onmessage: function (e) {
|
||||
var result = JSON.parse(e.data);
|
||||
for (index in result) {
|
||||
var cate = result[index].Category;
|
||||
var msg = result[index].Message;
|
||||
switch (cate) {
|
||||
case "DB":
|
||||
toastr.error(msg, "数据库操作发生异常");
|
||||
break;
|
||||
case "Users":
|
||||
toastr.success(msg, "新用户注册");
|
||||
break;
|
||||
case "App":
|
||||
toastr.warning(msg, "应用程序发生异常");
|
||||
break;
|
||||
}
|
||||
$('.header .nav').reloadWidget().notifi({
|
||||
url: 'NotiHub',
|
||||
callback: function (result) {
|
||||
var cate = result.Category;
|
||||
var msg = result.Message;
|
||||
switch (cate) {
|
||||
case "DB":
|
||||
toastr.error(msg, "数据库操作发生异常");
|
||||
break;
|
||||
case "Users":
|
||||
toastr.success(msg, "新用户注册");
|
||||
break;
|
||||
case "App":
|
||||
toastr.warning(msg, "应用程序发生异常");
|
||||
break;
|
||||
}
|
||||
if (result.length > 0) this.reloadWidget();
|
||||
if (result) this.reloadWidget();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -286,74 +286,18 @@
|
|||
}
|
||||
return this;
|
||||
},
|
||||
msgHandler: function (options) {
|
||||
var settings = {
|
||||
url: 'api/WS',
|
||||
interval: 10000,
|
||||
sendMessage: '',
|
||||
timerHandler: null,
|
||||
onopen: function (e) { },
|
||||
onmessage: function (e) { },
|
||||
onclose: function (e) { },
|
||||
errorHandler: function (e) { if (toastr && $.isFunction(toastr.error)) toastr.error("连接服务器失败!", "系统错误"); },
|
||||
loop: function () {
|
||||
var that = this;
|
||||
var uri = window.location.protocol + "//" + window.location.host + $.formatUrl(settings.url);
|
||||
$.bc({
|
||||
url: uri,
|
||||
id: this.sendMessage,
|
||||
method: "post",
|
||||
callback: function (result) {
|
||||
if (!result) {
|
||||
that.errorHandler.call(that.target);
|
||||
return;
|
||||
}
|
||||
that.onmessage.call(that.target, { data: JSON.stringify(result) });
|
||||
}
|
||||
});
|
||||
|
||||
if (this.timerHandler !== null) clearTimeout(this.timerHandler);
|
||||
this.timerHandler = setTimeout(function () { that.loop(); }, that.interval);
|
||||
notifi: function (options) {
|
||||
var op = $.extend({ url: '', method: 'rev', callback: false }, options);
|
||||
var connection = new signalR.HubConnectionBuilder().withUrl($.formatUrl(op.url)).build();
|
||||
var that = this;
|
||||
connection.on(op.method, function () {
|
||||
if ($.isFunction(op.callback)) {
|
||||
op.callback.apply(that, arguments);
|
||||
}
|
||||
};
|
||||
$.extend(settings, options, { target: this });
|
||||
settings.loop();
|
||||
return this;
|
||||
},
|
||||
socketHandler: function (options) {
|
||||
// WebSocket消息处理方法
|
||||
var settings = {
|
||||
url: 'WS',
|
||||
interval: 30000,
|
||||
sendMessage: 'keepalive',
|
||||
timerHandler: null,
|
||||
onopen: function (e) { },
|
||||
onerror: function (e) { },
|
||||
errorHandler: function (e) { if (window.toastr && $.isFunction(window.toastr.error)) toastr.error("连接服务器失败!", "系统错误"); },
|
||||
onmessage: function (e) { },
|
||||
onclose: function (e) { },
|
||||
loop: function (socket) {
|
||||
var that = this;
|
||||
if (socket.readyState === 1) {
|
||||
socket.send(this.sendMessage);
|
||||
if (this.timerHandler !== null) clearTimeout(this.timerHandler);
|
||||
this.timerHandler = setTimeout(function () { that.loop(socket); }, that.interval);
|
||||
}
|
||||
else {
|
||||
this.errorHandler();
|
||||
}
|
||||
}
|
||||
};
|
||||
$.extend(settings, options, { target: this });
|
||||
var uri = "ws://" + window.location.host + $.formatUrl(settings.url);
|
||||
var socket = new WebSocket(uri);
|
||||
socket.onopen = function (e) { settings.onopen.call(settings.target, e); settings.loop(socket); };
|
||||
socket.onerror = function (e) {
|
||||
settings.onerror.call(settings.target, e);
|
||||
settings.target.msgHandler(options);
|
||||
};
|
||||
socket.onmessage = function (e) { settings.onmessage.call(settings.target, e); };
|
||||
socket.onclose = function (e) { settings.onclose.call(settings.target, e); };
|
||||
});
|
||||
connection.start().catch(function (err) {
|
||||
return console.error(err.toString());
|
||||
});
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -1,14 +1,12 @@
|
|||
using Longbow.Cache;
|
||||
using Longbow.Configuration;
|
||||
using Longbow.Data;
|
||||
using Longbow.Web.WebSockets;
|
||||
using Newtonsoft.Json;
|
||||
using Longbow.Web.SignalR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
|
||||
namespace Bootstrap.DataAccess
|
||||
{
|
||||
|
@ -42,16 +40,18 @@ namespace Bootstrap.DataAccess
|
|||
cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@StackTrace", DBAccessFactory.ToDBValue(ex.StackTrace)));
|
||||
DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd);
|
||||
CacheManager.Clear(RetrieveExceptionsDataKey);
|
||||
ClearExceptions();
|
||||
|
||||
var category = "App";
|
||||
if (ex.GetType().IsSubclassOf(typeof(DbException))) category = "DB";
|
||||
WebSocketServerManager.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new MessageBody[] { new MessageBody() { Category = category, Message = ex.Message } }))));
|
||||
ClearExceptionsAsync();
|
||||
var message = new MessageBody() { Category = category, Message = ex.Message };
|
||||
SignalRManager.Get().SendAll(message);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private static void ClearExceptionsAsync()
|
||||
private static void ClearExceptions()
|
||||
{
|
||||
System.Threading.Tasks.Task.Run(() =>
|
||||
{
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
namespace Bootstrap.DataAccess
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageBody
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Category { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}-{1}", Category, Message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
using Longbow.Cache;
|
||||
using Longbow.Web.WebSockets;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Bootstrap.DataAccess
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class NotificationHelper
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private const string PullNotificationsIntervalDataKey = "NotificationHelper-PullNotificationsInterval";
|
||||
private static readonly List<MessageBody> MessagePool = new List<MessageBody>();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static void PushMessage(MessageBody message)
|
||||
{
|
||||
MessagePool.Add(message);
|
||||
CacheManager.Clear(PullNotificationsIntervalDataKey);
|
||||
|
||||
// websocket message push
|
||||
WebSocketServerManager.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new MessageBody[] { message }))));
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<MessageBody> RetrieveMessages()
|
||||
{
|
||||
return CacheManager.GetOrAdd(PullNotificationsIntervalDataKey, key =>
|
||||
{
|
||||
var msgs = new MessageBody[MessagePool.Count];
|
||||
MessagePool.CopyTo(msgs, 0);
|
||||
MessagePool.Clear();
|
||||
return new List<MessageBody>(msgs);
|
||||
});
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageBody
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Category { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}-{1}", Category, Message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
namespace Bootstrap.DataAccess
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class WSHelper
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="socket"></param>
|
||||
/// <param name="data"></param>
|
||||
public static byte[] WebSocketMessageHandler(byte[] data)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue