• ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(二) 实现聊天室连接


    ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(二) 实现聊天室连接

     

      上一篇已经简单介绍了layim WebUI即时通讯组件和获取数据的后台方法。现在要讨论的是SingalR的内容,之前都是直接贴代码。那么在贴代码之前先分析一下业务模型,顺便简单讲一下SingalR里的部分方法。

      进入正题,我们要做,即时通讯,就要考虑收发消息。我们先看推送消息的方法,找到 interface IHubConnectionContext<T> 接口定义,Hub文件里的Clients就是继承 IHubConnectionContext 接口,方法定义如下:

    复制代码
    public interface IHubConnectionContext<T>
        {
            T All { get; }
    
            T AllExcept(params string[] excludeConnectionIds);
            T Client(string connectionId);
            T Clients(IList<string> connectionIds);
            T Group(string groupName, params string[] excludeConnectionIds);
            T Groups(IList<string> groupNames, params string[] excludeConnectionIds);
            T User(string userId);
            T Users(IList<string> userIds);
        }
    复制代码
    • All全部连接服务器的客户端
    • AllExcept 除了某些客户端
    • Client 单独发送给某个指定客户端(connectionId是客户端连接服务器后自动生成的,单独单聊天可以使用这个方法,不过此次我没有使用)
    • Clients 多个指定客户端
    • Group 发送给组内成员,就像QQ群一样,所有群内成员都能接收到消息 单独聊天我采用此思路
    • Groups 发送给多个组,类似群 群发 多个群内的群成员都能接收到消息
    • User 没使用研究过(不做介绍)
    • Users没使用研究过(不做介绍)

      

      好,结下了,着重讲一下用Group 方法实现1对1聊天思路。其实原理还是组推送,只不过组里就两个人,大家都用过QQ聊天,聊天框里面就是两个人的对话消息。同理如果一个群里面就两个人的话,是不是也是两个人的对话消息。所以,如何保证组内就两个人呢,我采用id+id的思路。

      如图:假如用户1用户2都在线,用户1和用户2聊天的话,那么组ID就为用户1 ID+用户2 ID,(需要先将用户ID排序,例如小的在前,大的在后)思路有了,那么如果不选择直接拼接,也可以用其他方式生成两个用户间的唯一组ID,总之,组名不相同就可以了。

      下面在介绍一下,singalR 的 server 和 client。介绍之前呢,准备工作要做好:

      第一步:添加Hub文件

      第二步:简单在Hub文件里写几个方法,这里我自定义了HubName为 csHub,然后在 startup文件里配置hub路径

    复制代码
        [HubName("csHub")]
        public class CustomServiceHub : Hub
        {
            public Task Join()
            {
                return Clients.All.receiveMessage("某某人加入了");
            }
    
            public void SendMessage(string msg)
            {
               // Clients.Group
            }
        }
    复制代码
    复制代码
    using Microsoft.AspNet.SignalR;
    using Microsoft.Owin;
    using Owin;
    
    [assembly: OwinStartupAttribute(typeof(LayIM.Startup))]
    namespace LayIM
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.Map("/cs", map =>
                {
                    var hubConfiguration = new HubConfiguration()
                    {
                        EnableJSONP = true
                    };
                    map.RunSignalR(hubConfiguration);
                });
            }
        }
    }
    复制代码

      第三步:在页面中引用相应的js

        <script src="../Scripts/jquery-1.10.2.min.js"></script>
        <script src="../Scripts/jquery.signalR-2.1.2.min.js"></script>
        <script src="http://localhost:20237/cs/hubs"></script>

      注意看/cs/hubs 路径,这个是自动生成的一个js,在浏览器中打开,找一找代码,会发现,里面有server和client

    复制代码
    $.hubConnection.prototype.createHubProxies = function () {
            var proxies = {};
            this.starting(function () {
                // Register the hub proxies as subscribed
                // (instance, shouldSubscribe)
                registerHubProxies(proxies, true);
    
                this._registerSubscribedHubs();
            }).disconnected(function () {
                // Unsubscribe all hub proxies when we "disconnect".  This is to ensure that we do not re-add functional call backs.
                // (instance, shouldSubscribe)
                registerHubProxies(proxies, false);
            });
    
            proxies['csHub'] = this.createHubProxy('csHub'); //创建hub
            proxies['csHub'].client = { };//在client中自定义添加方法需要前端实现,一般接收数据的方法定义在client里面
            proxies['csHub'].server = { //server里面实现了Hub文件中相对应的调用方法,注意:他会自动把首字母大写的改为小写。
                join: function () {
                    return proxies['csHub'].invoke.apply(proxies['csHub'], $.merge(["Join"], $.makeArray(arguments)));
                 },
    
                sendMessage: function (msg) {
                    return proxies['csHub'].invoke.apply(proxies['csHub'], $.merge(["SendMessage"], $.makeArray(arguments)));
                 }
            };
    
            return proxies;
        };
    复制代码

      第四步:连接服务器,看看是否成功,js中连接服务器的写法有多种。我这里常用的就是调用start 方法

    复制代码
     $.connection.hub.start({ jsonp: true }).done(function () {
                        //连接服务器
                        _this.proxy.proxyCS.server.join();
                        console.log('连接成功');
                    }).fail(function () {
                        console.log("连接失败");
                    });

        //这行代码是封装的截取的部分代码,主要为了下面演示连接服务器效果

        receiveCallBack: function (result) {
          console.log("你收到了新消息:" + result);
          }

     
    复制代码

      我们继续看一下页面运行效果,F12看看都发送了哪些请求

      我们看到有start,connect,poll,send等,查看一下start方法返回的数据 为 Response:started。连接成功了,再看看调用join之后返回的数据:

      好了配合上边的部分代码,到此为止,与singalR服务的连接就完成了。我们可以调用server的join方法发送数据,在调用client的receiveMessage方法接收数据。我把连接服务端的代码稍作封装了一下,只需要引用js(client.hub.js)然后前端初始化方法如下:

      var hubConfig = {
                serverUrl: 'http://localhost:20237/cs'
            };
            $(function () {
                csClient.init({serverUrl:hubConfig.serverUrl});//init中传入serverUrl,里面会自动调用连接服务器方法
            });

      最后,看一下client.hub.js代码

    复制代码
    (function ($) {
        var csHub = {
            option: {
                serverUrl: '',//singalr服务器url
                receiveCallBack: function (result) {
                    console.log("你收到了新消息:" + result);//用户自定义回调
                }
            },
            proxy: {
                proxyCS: null,//singalr客户端代理类
            },
            messageType: {
            },
            //client
            client: {
                init: function () {
                    //客户端 receiveMessage 方法
                    _this.proxy.proxyCS.client.receiveMessage = function (result) {
                        _this.option.receiveCallBack(result);
                    };
                }
            },
            init: function (option) {
                $.extend(_this.option, option);
                _this.server.init();//服务端代码初始化  
                _this.client.init();//客户端代码初始化
    
            },
            //server
            server: {
                //server初始化
                init: function () {
                    this.connect();
                    _this.proxy.proxyCS.client.clientOnConnectedCallBack = this.connectCallBack;
                },
                //连接服务器
                connect: function () {
                    $.connection.hub.url = _this.option.serverUrl;
                    _this.proxy.proxyCS = $.connection.csHub;
                    $.connection.hub.start({ jsonp: true }).done(function () {
                        //连接服务器
                        _this.proxy.proxyCS.server.join();
                        console.log('连接成功');
                    }).fail(function () {
                        console.log("连接失败");
                    });
                },
                //连接成功之后回调
                connectCallBack: function (result) {
                    console.log(result);
                }
            }
        };
        var _this = csHub;
        window.csClient = _this;
    })($);
    复制代码

      讲来将去还是需要贴一点代码上来,可能对于不熟悉singalR的同学来说有点难度,没关系,下一章进入实战开发环节,手把手教你用SingalR 把客服聊天室搭建起来。不熟悉singalR的同学可以尝试做一下小的demo。今天的singalR连接就写到这里吧。有问题记得留言哦。

    作者:丶Pz

    出处:https://www.cnblogs.com/panzi/p/5146571.html

    本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。

  • 相关阅读:
    C# Array.Sort 省内排序
    Centos7开机启动tomcat8
    使用GeoWebCache发布ArcGIS切片地图(实现高清电子地图)
    获取经纬度之间距离的Java工具类
    centos7上安装rar解压软件
    GeoServer之发布Geotiff存在的问题
    $GPRMC解析
    如何在IDEA单元测试中使用Scanner获取输入内容
    GeoServer修改使用内存
    Github无法访问解决办法
  • 原文地址:https://www.cnblogs.com/Jeely/p/11058520.html
Copyright © 2020-2023  润新知