话不多说,先上图
背景:
微信聊天,经常会遇见视频发不了,嗯,还有聊天不方便的问题,于是我就自己买了服务器,部署了一套可以直接在微信打开的网页进行聊天,这样只需要发送个url给朋友,就能聊天了!
由于自己无聊弄着玩的,代码比较粗糙,各位多指正!
1、首先安装SignalR,这步我就不做过多说明了
安装好以后在根目录新建一个Hubs文件夹,做用户的注册和通知
MessageHub.cs 文件
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
namespace SignalR.Hubs
{
[HubName("MessageHub")]
public class MessageHub : Hub
{
private readonly ChatTicker ticker;
public MessageHub()
{
ticker = ChatTicker.Instance;
}
public void register(string username, string group = "default")
{
var list = (List<SiginalRModel>)HttpRuntime.Cache.Get("msg_hs");
if (list == null)
{
list = new List<SiginalRModel>();
}
if (list.Any(x => x.connectionId == Context.ConnectionId))
{
Clients.Client(Context.ConnectionId).broadcastMessage("已经注册,无需再次注册");
}
else if (list.Any(x => x.name == username))
{
var model = list.Where(x => x.name == username && x.group == group).FirstOrDefault();
if (model != null)
{
//注册到全局
ticker.GlobalContext.Groups.Add(Context.ConnectionId, group);
Clients.Client(model.connectionId).exit();
ticker.GlobalContext.Groups.Remove(model.connectionId, group);
list.Remove(model);
model.connectionId = Context.ConnectionId;
list.Add(model);
Clients.Group(group).removeUserList(model.connectionId);
Thread.Sleep(200);
var gourpList = list.Where(x => x.group == group).ToList();
Clients.Group(group).appendUserList(Context.ConnectionId, gourpList);
HttpRuntime.Cache.Insert("msg_hs", list);
// Clients.Client(model.connectionId).broadcastMessage("名称重复,只能注册一个");
}
//Clients.Client(Context.ConnectionId).broadcastMessage("名称重复,只能注册一个");
}
else
{
list.Add(new SiginalRModel() { name = username, group = group, connectionId = Context.ConnectionId });
//注册到全局
ticker.GlobalContext.Groups.Add(Context.ConnectionId, group);
Thread.Sleep(200);
var gourpList = list.Where(x => x.group == group).ToList();
Clients.Group(group).appendUserList(Context.ConnectionId, gourpList);
HttpRuntime.Cache.Insert("msg_hs", list);
}
}
public void Say(string msg)
{
var list = (List<SiginalRModel>)HttpRuntime.Cache.Get("msg_hs");
if (list == null)
{
list = new List<SiginalRModel>();
}
var userModel = list.Where(x => x.connectionId == Context.ConnectionId).FirstOrDefault();
if (userModel != null )
{
Clients.Group(userModel.group).Say(userModel.name, msg);
}
}
public void Exit()
{
OnDisconnected(true);
}
public override Task OnDisconnected(bool s)
{
var list = (List<SiginalRModel>)HttpRuntime.Cache.Get("msg_hs");
if (list == null)
{
list = new List<SiginalRModel>();
}
var closeModel = list.Where(x => x.connectionId == Context.ConnectionId).FirstOrDefault();
if (closeModel != null)
{
list.Remove(closeModel);
Clients.Group(closeModel.group).removeUserList(Context.ConnectionId);
}
HttpRuntime.Cache.Insert("msg_hs", list);
return base.OnDisconnected(s);
}
}
public class ChatTicker
{
#region 实现一个单例
private static readonly ChatTicker _instance =
new ChatTicker(GlobalHost.ConnectionManager.GetHubContext<MessageHub>());
private readonly IHubContext m_context;
private ChatTicker(IHubContext context)
{
m_context = context;
//这里不能直接调用Sender,因为Sender是一个不退出的“死循环”,否则这个构造函数将不会退出。
//其他的流程也将不会再执行下去了。所以要采用异步的方式。
//Task.Run(() => Sender());
}
public IHubContext GlobalContext
{
get { return m_context; }
}
public static ChatTicker Instance
{
get { return _instance; }
}
#endregion
}
public class SiginalRModel {
public string connectionId { get; set; }
public string group { get; set; }
public string name { get; set; }
}
}
我把类和方法都写到一块了,大家最好是分开!