zoukankan      html  css  js  c++  java
  • Nginx+SignalR+Redis(一)windows

    Nginx+SignalR+Redis(一)

    MVC中SignalR服务端搭建

    前言, SignalR即时通讯功能里面有一些前端的类库不是我自己写的,我是大自然的搬运工。我只是改吧改吧

    最终效果演示

    没个GIF的演示我会拿出来秀?

    看上去是不是感觉还可以? 那下面我讲解一下开发步骤。

    创建MVC项目

     

    为MVC项目在NuGet中引用SignalR

    这里用到了NuGet,网上也有很多资源讲解怎么使用这个。我这里只大概讲解一下。首先打开[工具]-[NuGet 程序包管理器]-[管理解决方案的 NuGet 程序包]

     

    接下来在出现的界面中将程序包源改成:联机,然后搜索SignalR。接下来自行解决~.~

    使用SignalR

    需要通过Startup类来配置OWIN程序,所以要在项目中加入一个OWIN Startup类

     

    创建好之后配置注入Redis,设置跨域,并开启SignalR其中细节不一一介绍

    好了下面,我们再为SignalR创建一个集线器Hubs,我的习惯是在项目中创建一个Hubs目录,然后把需要创建的HubClass放到里面。下面先在项目中创建一个Hubs目录,再在目录上单击右键选择[添加]-[新建项]选择[SignalR 集线器类]

     

    点击确定,再把新建的HubClass中的Hello函数干掉。然后在类上增加一个特性:[HubName("systemHub")]。既然是要聊天那么自然离不开用户,为了方便管理我建立了一个用户的实体类UserDetail

    既然用户类有了,那么我们可以在Hub里面创建一个用户池,用来管理在线用户。

    可以将用户池保存至Redis

    现在用户池有了,下面需要实现三个功能就能进行登录、上线、下线、私聊操作了。这是下面的逻辑处理代码:

    using CacheRedis;
    using Microsoft.AspNet.SignalR;
    using Microsoft.AspNet.SignalR.Hubs;
    using SignalChat.Model;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace SignalRChat.Hubs
    {
        [HubName("systemHub")]
        public class SystemHub : Hub
        {
            /// <summary>
            /// 登录连线
            /// </summary>
            /// <param name="userID">用户ID</param>
            /// <param name="userName">用户名</param>
            /// <param name="deptName">部门名</param>
            public void Connect(string userID, string userName, string deptName)
            {
                var id = Context.ConnectionId;
    
                List<UserDetail> ConnectedUsers = RedisCache.Hash_GetAll<UserDetail>(Const.UserPool);
    
                if (ConnectedUsers.Count(a => a.ConnectionId == id) == 0)
                {
                    if (ConnectedUsers.Count(x => x.UserID == userID) > 0)
                    {
                        var items = ConnectedUsers.Where(x => x.UserID == userID).ToList();
                        foreach (var item in items)
                        {
                            Clients.AllExcept(id).onUserDisconnected(item.ConnectionId, item.UserName);
                        }
                        ConnectedUsers.RemoveAll(x => x.UserID == userID);
                    }
    
                    //添加在线人员
                    RedisCache.Hash_Set(Const.UserPool, id, new UserDetail { ConnectionId = id, UserID = userID, UserName = userName, DeptName = deptName, LoginTime = DateTime.Now });
    
                    // 反馈信息给登录者
                    Clients.Caller.onConnected(id, userName, ConnectedUsers);
    
                    // 通知所有用户,有新用户连接
                    Clients.AllExcept(id).onNewUserConnected(id, userID, userName, deptName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
    
                }
                else
                {
                    //已经连接的用户
                }
            }
    
            /// <summary>
            /// 发送私聊
            /// </summary>
            /// <param name="toUserId">接收方用户连接ID</param>
            /// <param name="message">内容</param>
            public void SendPrivateMessage(string toUserId, string message)
            {
                string fromUserId = Context.ConnectionId;
                List<UserDetail> ConnectedUsers = RedisCache.Hash_GetAll<UserDetail>(Const.UserPool);
                var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId);
                var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId);
    
                if (toUser != null && fromUser != null)
                {   // send to 
                    Clients.Client(toUserId).receivePrivateMessage(fromUserId, fromUser.UserName, message);
    
                    // send to caller user
                    //Clients.Caller.sendPrivateMessage(toUserId, fromUser.UserName, message);
                }
                else
                {
                    //表示对方不在线
                    Clients.Caller.absentSubscriber();
                }
            }
    
            /// <summary>
            /// 离线
            /// </summary>
            public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
            {
                var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
                if (item != null)
                {
                    Clients.All.onUserDisconnected(item.ConnectionId, item.UserName);   //调用客户端用户离线通知
                    ConnectedUsers.Remove(item);
                }
                return base.OnDisconnected(stopCalled);
            }
        }
    }

    我这里写的逻辑只是一个简单的示例,这个可以根据自己的想法和需求任意发挥。至此SignalR服务端已经建立完毕。

    下面开始建立SignalR浏览器客户端在解决方案上右键单击添加新建项目,如下图所示

    页面视图引入一下js
     

    
    
    

    其中<script src="http://localhost:8080/signalr/hubs"></script>是signalr服务端地址

    一下为页面signalr的js介绍

    //实例SystemHub,首字母必须小写才能调用
    
    var systemHub = $.connection.systemHub;
    
    //开始链接到集线器
    
    $.connection.hub.start().done(function () {
    
         //调用服务端函数Connect(首字母小写)以及传递客户端参数进行上线操作
    
        systemHub.server.connect(userid, username, deptname);
    
      });
    
      //新用户上线
    
      systemHub.client.onNewUserConnected = function (id, userID, userName, deptName, loginTime) {
    
         //定义onNewUserConnected客户端函数供服务端调用
    
    };
    
     //用户离线
    
     systemHub.client.onUserDisconnected = function (id, userName) {
    
         //定义onUserDisconnected客户端函数供服务端调用
    
     };
    
     //发送消息时,对方已不在线
    
     systemHub.client.absentSubscriber = function () {
    
         //定义absentSubscriber客户端函数供服务端调用
    
     };
    
     //接收消息
    
     systemHub.client.receivePrivateMessage = function (fromUserId, useame, message) {
    
         //定义receivePrivateMessage客户端函数供服务端调用
    
     };
    
     //发送消息
    
     systemHub.server.sendPrivateMessage(ChatCore.nowchat.id, data.content);

    SignalRChat

    作者太难了给作者点辛苦费吧

  • 相关阅读:
    sublime显示当前文件的编码格式
    关于jquery中html()、text()、val()的区别
    bit,Byte,B,KB,MB,GB
    python之序列操作
    编程常用密匙
    js数组操作
    ob函数的使用
    php使用zlib实现gzip压缩
    js兼容性汇总
    centos7下源码编译安装mysql5.7
  • 原文地址:https://www.cnblogs.com/chuizilong/p/10347158.html
Copyright © 2011-2022 走看看