SignalR初探

一.认识SingalR

1.Http协议是浏览器端主动发请求,服务器不能主动发起请求。可以使用ajax或者原生websocket开发,但是难度大。但是使用SignalR,简化了WebSocket开发。

2.SignalR集线器类(SignalR持久连接)是底层机制。

3.可以实现即时通讯。SignalR有三种传输模式:LongLooping(长轮询)、WebSocket(HTML5的WEB套接字)、Forever Frame(隐藏框架的长请求连接)

二.编写代码

1.前端代码





    
    OnLineUser
@*注意这个文件是动态创建的,引入的时候尽量放在最后,还有jq和singalR的引入最好按顺序进行引入否则可能会报错*@
    
    
    


    
    
    


2.后端Hub(TestHub)代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using StackExchange.Redis;
using System.IO;
using System.Text;
namespace SingalRProject
{
public class OnLineUserHub:Hub
{
public async Task Login(string userName)
{
using(ConnectionMultiplexer redis=ConnectionMultiplexer.Connect("localhost:6379"))
{
IDatabase db=readis.GetDatabase();
RedisKey strs="key"+this.ContextConnectionId;
var str=await db.StringGetAsync(strs);
if(str.ToString()==userName)
{
await OnDisConectionted(false);
return;
}
var db.StringSetAsync("key"+UserName,true);
await db.StringSetASync("key_UserName"+this.Context.ConnectionId,userName);
await db.SetAddAsync("key_User",UserName);
RedisValue[]userNames=await db.SetMemberAsync("Key_User");
ReduisKey[]userNamesOnlineKeys=userNames.Select(e=>(RedisKey)("key"+e)).ToArray();
Dictionarydata=new Dictionary();
for(int i=0lu
//升级版
namespace SingalRProject
{
public class OnLineUserHub:HUb
{
private static connStr="localhost:6379"
private Object obj=new Object;
private static ConnectionMultiplexer redis;
private static ConnectionMultiplexer _regist
{
get
{
if(redis==null)
{
lock(obj)
{
if(redis==null||redis.IsConnected)
{
redis=redis.Connect(connStr);
}
return redis;
}
}
}
}
public async Task Db()
{
return _redis.GetDatabase();
}

}
}

捕获SignalR的异常

public class ExceptoinHubPipelineMoudule:HubPipelineModule
{
protected override void OnIncomingError(ExceptionContext exceptionContext,IHubIncomingInvokerContext invokerContext)
{
//可以把异常计入到日志中
base.OnIncomingError(exceptionContext,invokerContext);
 //exceptionContext.Error就是一个异常对象 可以记录到日志里面  记录到分布式的日志
WriteLog(exceptionContext.Error.Message);
dynamic caller=invokerContext.Hub.Clients.Callser;
//把异常信息传递出去
caller.onServerError(exceptionContext.Error.Message);
}
private static string path=@"XXXXX";
public void WriteLog(string ErrorInfo)
{
using(Stream fs=new FileStream(path,FileMode.OpenOrCreate))
{
byte[]info=Encoding.UTF8.GetBytes(ErrorInfo);
fs.Write(info,0,info.Length);
}
}
}
//接着再Global.asax.cs中进行全局的注册
namespace SignalProhect
{
public class MvcApplication:Syste.Web.HttpApplication
{
proteted void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Route);
//进行全局注册SignalR异常捕获
GlobalHost.HubPipeline.AddModule(new HubException());
}
}
}

接下来进行组的添加和删除,在同一组内可以互相进行通信

public class GroupHub:Hub
{
public void AddGroup(string groupName)
{
Groups.Add(this.Context.ConnectionId,groupName);
Clients.All.Hello();
}
public void SendGroupMsg(string grouName,string msg)
{
Clients.OthersInGroup(grouName).onMessage(msg);
Clients.OthersInGroup(grouName).OnMessage2(msg)
}
}

前端页面





    
    
    
    
    



    
消息:
组名: 组名: 消息:

 

你可能感兴趣的:(SignalR初探)