微信互动大屏 霸屏 抢红包 源码及所需技术


     当时这个项目是2018年中旬的时候帮一家传媒公司开发的,里面功能很多,但涉及到的技术点并不多,可能是客户需要的功能比较少的原因吧。但还是相当繁琐的,因为里面有很多功能点。
      霸屏,抢红包,互动,众筹,提现,打赏,打赏动画,代理等。
      项目为.net 4.5,因为当时在考虑大屏与用户要实时的保持同步,用户与用户要保持连接,所以没选择PHP(不是因为php不好,而是我们公司的技术栈为.net,只能用php做一些简单的cms和网站,php大神勿喷)。开始想使用的是轮询,想着有延时,而且并发上来就得炸。后来考虑长连接和H5 WebSocket,起初已经开始着手自己实现了,后来了解到微软对此有专门的解决方案,那就是【SignalR】 ,而且使用起来很简单,稳定性也比较靠谱,会根据用户的所处环境,自动选择轮询,长连接还是WebSocket。

     文章最下面是项目效果,当时客户开展了20多家酒吧吧,巅峰的时候也就不到1000个人在线,当时用的服务器是8g,8核的,cpu没超过30%,内存在4个G左右,可能是用户规模还没上来。数据库使用的是Sql server 2008R2,iis 8.5。抢红包这块使用的是redis+lua脚本,比较靠谱。因为当时的霸屏会出现队列的情况,所以也是使用的redis+lua实现的。

     设计思路就是每个酒吧,设置一个单独的聊天室,每个用户通过二维码进入之后绑定进该酒吧的聊天室,聊天信息与霸屏信息推送至大屏。刚好signalr都有类型的功能,signalr怎么使用就不在复述了,网上搜下很多,这里只谈下设计思路。

   下面是js用户进入的代码

        $.connection.hub.qs = { nId:nid }; //后台生成的针对酒吧唯一ID   
            var chat = $.connection.chatHub;
            chatClientCore = chat.client;
       
            $.connection.hub.start().done(function () {
                chatServerCore = chat.server;       
                console.log("连接成功!");
            });
            $.connection.hub.disconnected(function () {
                if (reConnect == undefined || reConnect==null) {
                    reConnectServer();//重新连接
                }                      
            });

 当用户连接入聊天室的时候,在后台将其加入至该酒吧的集合中

      public override Task OnConnected()
        {            
            //数据连接的时候
            //UserInfo u = new SessionRedisHub(Context).GetLoginUser();
            string cid = Context.ConnectionId;
            //此处nid从前太连接是传过来的参数获取
            int nId = Convert.ToInt32(Context.QueryString["nId"]);
            Groups.Add(cid, "node_" + nId);
            return base.OnConnected();
        }

 这里谈到一个细节,就是如果需要私聊在连接上来的时候就得把cid给保存起来。我们项目中是使用redis做session的,具体实现细节,网上也能搜到,这里没记录网页地址。这里需要着重提一下,就是自己实现的话需要在Startup.ConfigureSignalR中注册IUserIdProvider,代码如下

public static void ConfigureSignalR(IAppBuilder app)
        {
            var userIdProvider = new MyUserFactory();
            GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => userIdProvider);
            //var config = new HubConfiguration();
            //app.MapSignalR("/chat",config);
            app.MapSignalR();
        }


//MyUserFactory
public class MyUserFactory : IUserIdProvider
    {
        /// <summary>
        /// 获取当前登陆用户存储的sessionid
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public string GetUserId(IRequest request)
        {
            string cnnId = new SessionRedis(request).SessionId;
            if (!string.IsNullOrEmpty(cnnId))
                return cnnId;            
            return "404";
        }
    }

  发送私聊的时候直接取sessionID进行user发送就可以了

 //群聊代码
 ChatToNodeInfo nInfo = ChatCorrelation.GetChatNode(cId);
 Clients.OthersInGroup("node_" + nInfo.MNId).BPtoScreen(nInfo);

//私聊代码
Clients.User(new SessionRedisHub(Context).SessionId).test(cPageInfo);  

//推送大屏
IHubContext ScreenHub = GlobalHost.ConnectionManager.GetHubContext<ScreenHub>();
nInfo.PostTime = DateTime.Now.ToString("MM-dd HH:mm");
ScreenHub.Clients.Group("screen_"+nInfo.MNId).BPtoScreen(nInfo);

   大屏和聊天室类似,就是加入的组名不能相同,因为大屏都是单方面接受推送,聊天室的内容想推送至大屏的话,只需要获取到大屏的Hub即可完成推送。

   大体实现方案就是这样,使用signal之后实现起来还是比较简单的,具体细节还得看具体业务。

   抢红包和霸屏在时间上控制都是使用redis做的,下次有时间在写。

   项目部分图片

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值