SignalR 公共类

安装
注:1.本地使用控制台启动调试时 如果地址用了ip需要用管理员身份运行项目,如果使用localhost则不需要
2.客户端必须要有一个方法
安装自托管包 install-package Microsoft.AspNet.SignalR.SelfHost 第一步
安装跨域包 Install-Package Microsoft.Owin.Cors 第二步

Install-Package Microsoft.AspNet.SignalR
–install-package Microsoft.Owin.Host.HttpListener
–install-package Microsoft.Owin.Hosting
–应用程序作为客户端时的中间件 Install-Package Microsoft.AspNet.SignalR.Client

–https
netsh http add sslcert ipport=0.0.0.0:8082
appid={12345678-db90-4b66-8b01-88f7af2e36bf}
certhash=d37b844594e5c23702ef4e6bd17719a079b9bdf

netsh http show sslcert ipport=0.0.0.0:8082

MainHub.cs 类

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace MyHub
{
    [MyHubAuthorize]
    public class MainHub : Hub
    {
        /// <summary>
        /// 事件 接收客户端消息
        /// </summary>
        public static event Action<HubCallerContext,string> ReceivedData;
        /// <summary>
        /// 事件 新链接
        /// </summary>
        public static event Action<HubCallerContext> NewConnected;

        public static ConcurrentDictionary<string, HubCallerContext> ConnectionDictionary = new ConcurrentDictionary<string, HubCallerContext>();

        /// <summary>
        /// 服务端方法 提供给客户端调用,从客户端传递消息到服务端
        /// </summary>
        /// <param name="data"></param>
        public void FromClient(string data)
        {
            ReceivedData?.Invoke(Context, data);
        }

        /// <summary>
        /// 服务端方法 提供给服务端调用,从服务端传递消息到客户端 传给指定客户端
        /// </summary>
        /// <param name="ConnectionId"></param>
        /// <param name="data"></param>
        public static void ToClient(string ConnectionId, object data)
        {
            var t = Task.Factory.StartNew(() =>
            {
                try
                {
                    GlobalHost.ConnectionManager.GetHubContext<MainHub>().Clients.Client(ConnectionId).OnMessage(data);//调用客户端OnMessage()方法
                    //this.Clients.Client(ConnectionId).OnMessage(data);
                }
                catch (Exception e)
                {
                }
            });

        }
        /// <summary>
        /// 服务端方法 提供给服务端调用,调用客户端OnStop()方法 从客户端断开链接
        /// </summary>
        /// <param name="ConnectionId"></param>
        public static void CloseClient(string ConnectionId)
        {
            GlobalHost.ConnectionManager.GetHubContext<MainHub>().Clients.Client(ConnectionId).OnStop();//调用客户端OnStop()方法 从客户端断开链接
            //this.Clients.Client(ConnectionId).OnMessage(data);
        }

        /// <summary>
        /// 服务端方法 提供给服务端调用,从服务端传递消息到客户端 传给所有客户端
        /// </summary>
        /// <param name="data"></param>
        public static void ToClient(object data)
        {
            var t = Task.Factory.StartNew(() =>
            {
                try
                {
                    GlobalHost.ConnectionManager.GetHubContext<MainHub>().Clients.All.OnMessage(data);
                    //Clients.All.OnMessage(data);
                }
                catch (Exception e)
                {
                }
            });

        }
        public override Task OnConnected()
        {
            try
            {
                if (!ConnectionDictionary.ContainsKey(Context.ConnectionId))
                {
                    //Clients.Caller.OnStop();
                    if(!ConnectionDictionary.TryAdd(Context.ConnectionId, Context))
                    {
                        Clients.Caller.OnStop();
                    }
                }
                string QueryString = "";
                foreach (var item in Context.QueryString)
                {
                    if (item.Key != "connectionToken")
                    {
                        QueryString += item.Key + ":" + item.Value + " ";
                    }
                }
            }
            catch
            {
            }

            NewConnected?.Invoke(Context);
            return base.OnConnected();
        }
        public override Task OnReconnected()
        {
            try
            {
                if (!ConnectionDictionary.ContainsKey(Context.ConnectionId))
                {
                    if (!ConnectionDictionary.TryAdd(Context.ConnectionId, Context))
                    {
                        Clients.Caller.OnStop();
                    }
                }
            }
            catch
            {
            }
            NewConnected?.Invoke(Context);
            
            return base.OnReconnected();
        }
        public override Task OnDisconnected(bool stopCalled)
        {
            try
            {
                if (ConnectionDictionary.ContainsKey(Context.ConnectionId))
                {
                    HubCallerContext outval;
                    ConnectionDictionary.TryRemove(Context.ConnectionId, out outval);
                }
            }
            catch
            {
            }
            return base.OnDisconnected(stopCalled);
        }
    }
}

MyHubAuthorize.cs 过滤器类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace MyHub
{
    public class MyHubAuthorize: AuthorizeAttribute
    {
        /// <summary>
        /// 连接权限
        /// </summary>
        /// <param name="hubDescriptor"></param>
        /// <param name="request"></param>
        /// <returns>true 允许连接 触发OnConnected false 不允许连接</returns>
        public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
        {
            return true;
        }
     
        /// <summary>
        /// 调用服务端方法权限
        /// </summary>
        /// <param name="hubIncomingInvokerContext"></param>
        /// <param name="appliesToMethod"></param>
        /// <returns></returns>
        public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
        {
            return true;
        }
    }
}

Startup.cs

using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

[assembly: OwinStartup(typeof(Server.Startup))]
namespace Server
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //开启cors
            app.UseCors(CorsOptions.AllowAll);
            //开启JSONP,并显示详细问题
            var config = new HubConfiguration() { EnableJSONP = true, EnableDetailedErrors = true };
            app.MapSignalR(config);
        }
    }
}

业务逻辑层调用 BLL

#define Release
//#define必须放在最顶部 Release 调试模式标志 Debug 发布模式标志 Release
using SuperWebSocket;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Owin.Hosting;
using MyHub;
using Microsoft.AspNet.SignalR.Hubs;


namespace BLL
{
    public class SignalRServerBLL
    {
        private bool _isRunning = true;
        private Thread _MainThread = null;
        private int _SleepTime = 0;
        private string _HttpListenerUrl = Properties.Settings1.Default.HttpListenerUrl;
        private IDisposable _web_app;
        public SignalRServerBLL()
        {
            try
            {
                _MainThread = new Thread(new ThreadStart(Process));
                MainHub.ReceivedData += my_ReceivedData;
                MainHub.NewConnected += my_NewConnected;
            }
            catch (Exception ex)
            {
                Service1.logger.Error(ex.ToString());
            }
        }

        public void Start()
        {
            try
            {
                //本地使用控制台启动调试时 如果地址用了ip需要用管理员身份运行项目(管理员身份运行VS),如果使用localhost则不需要
                _web_app = WebApp.Start<Startup>(_HttpListenerUrl);
                _MainThread.Start();
                Service1.logger.Info(string.Format("Service Start {0}...", _web_app!=null?"Success":"Fail"));
                Service1.logger.Info($"HttpListenerUrl {_HttpListenerUrl}...");
            }
            catch (Exception ex)
            {
#if Debug
                throw;
#endif
                Service1.logger.Error(ex.ToString());
            }
        }

        public void Dispose()
        {
            _isRunning = false;
            _web_app?.Dispose();
            Service1.logger.Info("Service Dispose...");
        }


#region 
        /// <summary>
        /// 新连接处理
        /// </summary>
        /// <param name="session"></param>
        private void my_NewConnected(HubCallerContext Context)
        {
            try
            {
                //do..
            }
            catch (Exception ex)
            {
#if Debug
                throw;
#endif
                Service1.logger.Error(ex.ToString());
            }
        }

        /// <summary>
        /// 消息处理
        /// </summary>
        /// <param name="session"></param>
        /// <param name="data"></param>
        private void my_ReceivedData(HubCallerContext Context, string data)
        {
            try
            {
               //do..
               //var Path_eng = MainHub.ConnectionDictionary.Where(C => C.Value.QueryString["Language"] != null && C.Value.QueryString["Language"].ToString().ToLower() == "eng");
                 MainHub.ToClient(Context.ConnectionId, data);
            }
            catch (Exception ex)
            {
#if Debug
                throw;
#endif
                Service1.logger.Error(ex.ToString());
            }
        }
#endregion

#region 
        private void Process()
        {
            do
            {
               //do..
                Thread.Sleep(_SleepTime);
            } while (_isRunning);
        }
#endregion

    }
}

网页客户端

mySignalR.js

//創建SingnalR公共模型 LCJ 2018年4月13日11:30:57
var mySignalR = function () {
    this.Hub = null;//集線器
    this.Proxy = null;//代理
    this.Url = null;//鏈接地址
    this.QueryString = {};//請求參數
    this.OnEven = {};//客戶端事件
    this.stateChanged = null;//鏈接狀態改變事件
};
mySignalR.prototype.SendMessage = function (data) {//客戶端發送消息到服務器方法
    //调用 server 端的方法 服务端要有方法“FromClient”
    this.Proxy.invoke("FromClient", data).done(function (msg) {
        console.log(msg);
    }).fail(function (data) {
        console.log(data);
    });
};
mySignalR.prototype.Start = function () {//初始化,啟動鏈接
    if (this.Proxy != null) return;//防止多次调用Start() 开启多个链接
    var Conn = $.hubConnection(this.Url);

    Conn.qs = this.QueryString;
    //代理
    this.Proxy = Conn.createHubProxy(this.Hub);

    //定义客户端方法(必须要有一个)
    for (var myEven in this.OnEven) {//批量註冊客戶端方法
        this.Proxy.on(myEven, this.OnEven[myEven]);
    }
    //this.Proxy.on("OnMessage", this.OnMessage);
    this.Proxy.on("OnStop", function () {
        this.stop();
    });
    Conn.connectionSlow(function () {
        console.log("connectionSlow");
    });
    Conn.stateChanged(this.stateChanged);
    Conn.reconnecting(function () {
        console.log("重新连接中");
    });
    Conn.reconnected(function () {
        console.log("重新连接成功");
    });
    Conn.disconnected(function () {
        console.log("连接中断");
        ((CurrentConn)=>{
            //this 當前conn對象
            setTimeout(()=>{ CurrentConn.start(); }, 5000);
        })(this);
    });
    Conn.error(function (error) {
        console.log(error);
    });
    Conn.start().done(function (data) {
        //console.log(_SinglaR_News_conn.state);
        //console.log(data);
    }).fail(function (data) {
        //console.log(_SinglaR_News_conn.state);
        console.log("start fail:" + data);
    });
};

新建实例

var _SinglaR= new mySignalR();
_SinglaR.Hub = "MainHub";//服务端集线器类名
_SinglaR.Url = _SinglaR_Url;
//_SinglaR.QueryString.Language = _Language;//自定义参数_SinglaR.QueryString.xxx
_SinglaR.OnEven.OnMessage = function (data) {//注册客户端方法"OnMessage" 该名字可自定义,服务端调用该名字 OnEven.xx可以定义多个方法
    //do...
};

_SinglaR.stateChanged = function () {//鏈接狀態改變事件
    //this 當前conn對象
    if (this.state == 1) {
        console.log("连接成功");
    }
};
_SinglaR.Start();//连接
//_SinglaR.SendMessage("");//客戶端發送消息到服務器方法 服务端要有方法“FromClient”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值