重构代码:移除WebSockets相关逻辑,使用SignalR

This commit is contained in:
Argo-MacBookPro 2018-10-12 14:04:49 +08:00
parent b528810516
commit 26581b6b3b
12 changed files with 3814 additions and 207 deletions

View File

@ -1,5 +1,6 @@
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Bootstrap.Security; using Bootstrap.Security;
using Longbow.Web.SignalR;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Linq; using System.Linq;
@ -26,10 +27,10 @@ namespace Bootstrap.Admin.Controllers.Api
/// <param name="user"></param> /// <param name="user"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
public bool Post([FromBody] User user) public bool Post([FromServices]ISignalRHubContext<SignalRHub> hub, [FromBody]User user)
{ {
var ret = UserHelper.SaveUser(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; return ret;
} }
} }

View File

@ -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();
}
}
}

View File

@ -7,7 +7,7 @@ using Longbow.Configuration;
using Longbow.Data; using Longbow.Data;
using Longbow.Logging; using Longbow.Logging;
using Longbow.Web; using Longbow.Web;
using Longbow.Web.WebSockets; using Longbow.Web.SignalR;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
@ -50,6 +50,7 @@ namespace Bootstrap.Admin
.SetApplicationName(Configuration["ApplicationName"]) .SetApplicationName(Configuration["ApplicationName"])
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"])); .PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyPath"]));
if (Configuration["DisableAutomaticKeyGeneration"] == "True") dataProtectionBuilder.DisableAutomaticKeyGeneration(); if (Configuration["DisableAutomaticKeyGeneration"] == "True") dataProtectionBuilder.DisableAutomaticKeyGeneration();
services.AddSignalRManager();
services.AddMvc(options => services.AddMvc(options =>
{ {
options.Filters.Add<BootstrapAdminAuthorizeFilter>(); options.Filters.Add<BootstrapAdminAuthorizeFilter>();
@ -81,8 +82,8 @@ namespace Bootstrap.Admin
app.UseStaticFiles(); app.UseStaticFiles();
app.UseAuthentication(); app.UseAuthentication();
app.UseBootstrapAdminAuthorization(); app.UseBootstrapAdminAuthorization();
app.UseWebSocketHandler(options => options.UseAuthentication = true, WSHelper.WebSocketMessageHandler);
app.UseCacheManagerCorsHandler(); app.UseCacheManagerCorsHandler();
app.UseSignalR(routes => { routes.MapHub("/NotiHub"); });
app.UseMvc(routes => app.UseMvc(routes =>
{ {
routes.MapRoute( routes.MapRoute(

View File

@ -18,11 +18,13 @@
<environment include="Development"> <environment include="Development">
<script src="~/js/sweetalert.js"></script> <script src="~/js/sweetalert.js"></script>
<script src="~/js/jquery.mCustomScrollbar.js"></script> <script src="~/js/jquery.mCustomScrollbar.js"></script>
<script src="~/js/signalr.js"></script>
<script src="~/js/toastr.js"></script> <script src="~/js/toastr.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/js/sweetalert.min.js"></script> <script src="~/js/sweetalert.min.js"></script>
<script src="~/js/jquery.mCustomScrollbar.concat.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> <script src="~/js/toastr.min.js"></script>
</environment> </environment>
<script src="~/js/jquery.dcjqaccordion.2.7.js"></script> <script src="~/js/jquery.dcjqaccordion.2.7.js"></script>

View File

@ -216,25 +216,23 @@ $(function () {
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
// load widget data // load widget data
$('.header .nav').reloadWidget().socketHandler({ $('.header .nav').reloadWidget().notifi({
onmessage: function (e) { url: 'NotiHub',
var result = JSON.parse(e.data); callback: function (result) {
for (index in result) { var cate = result.Category;
var cate = result[index].Category; var msg = result.Message;
var msg = result[index].Message; switch (cate) {
switch (cate) { case "DB":
case "DB": toastr.error(msg, "数据库操作发生异常");
toastr.error(msg, "数据库操作发生异常"); break;
break; case "Users":
case "Users": toastr.success(msg, "新用户注册");
toastr.success(msg, "新用户注册"); break;
break; case "App":
case "App": toastr.warning(msg, "应用程序发生异常");
toastr.warning(msg, "应用程序发生异常"); break;
break;
}
} }
if (result.length > 0) this.reloadWidget(); if (result) this.reloadWidget();
} }
}); });

View File

@ -286,74 +286,18 @@
} }
return this; return this;
}, },
msgHandler: function (options) { notifi: function (options) {
var settings = { var op = $.extend({ url: '', method: 'rev', callback: false }, options);
url: 'api/WS', var connection = new signalR.HubConnectionBuilder().withUrl($.formatUrl(op.url)).build();
interval: 10000, var that = this;
sendMessage: '', connection.on(op.method, function () {
timerHandler: null, if ($.isFunction(op.callback)) {
onopen: function (e) { }, op.callback.apply(that, arguments);
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);
} }
}; });
$.extend(settings, options, { target: this }); connection.start().catch(function (err) {
settings.loop(); return console.error(err.toString());
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); };
return this; return this;
} }
}); });

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,12 @@
using Longbow.Cache; using Longbow.Cache;
using Longbow.Configuration; using Longbow.Configuration;
using Longbow.Data; using Longbow.Data;
using Longbow.Web.WebSockets; using Longbow.Web.SignalR;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Data; using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Text;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
@ -42,16 +40,18 @@ namespace Bootstrap.DataAccess
cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@StackTrace", DBAccessFactory.ToDBValue(ex.StackTrace))); cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@StackTrace", DBAccessFactory.ToDBValue(ex.StackTrace)));
DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd); DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd);
CacheManager.Clear(RetrieveExceptionsDataKey); CacheManager.Clear(RetrieveExceptionsDataKey);
ClearExceptions();
var category = "App"; var category = "App";
if (ex.GetType().IsSubclassOf(typeof(DbException))) category = "DB"; 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 } })))); var message = new MessageBody() { Category = category, Message = ex.Message };
ClearExceptionsAsync(); SignalRManager.Get().SendAll(message);
} }
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
private static void ClearExceptionsAsync() private static void ClearExceptions()
{ {
System.Threading.Tasks.Task.Run(() => System.Threading.Tasks.Task.Run(() =>
{ {

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}