重构代码:移除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.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;
}
}

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.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(

View File

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

View File

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

View File

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

View File

@ -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(() =>
{

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