一、前言

继续上一章的补充,这章介绍使用私聊的功能。主要通过一个方法   Clients.Client(Context.ConnectionId).showMessage(msg); SignalR框架就会给你找对对应的集线器客户端并调用客户端注册好的showMessage方法,下面具体实例和注意地方

二、干活实战开始

创建一个User类,记录用户名字和集线器代理ID

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SignalRTest
{
    public class User
    {
        public string Name { get; set; }

        public string ConnectionId { get; set; }
    }
}

TestHub代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Newtonsoft.Json;

namespace SignalRTest
{
    //Hub的别名,方便前台调用
    [HubName("testHHH")]
    public class TestHub : Hub
    {
        /// <summary>
        /// 用户列表,静态
        /// </summary>
        public static List<User> list = new List<User>();

        /// <summary>
        /// 模拟标示用户身份,静态
        /// </summary>
        ;

        /// <summary>
        /// 重写连接方法,如果用户不存在,则新建用户
        /// </summary>
        /// <returns></returns>
        public override System.Threading.Tasks.Task OnConnected()
        {
            var user = list.Where(u => u.ConnectionId == Context.ConnectionId).FirstOrDefault();
            if (user == null)
            {
                //注册用户
                list.Add(new User() { Name = "员工" + i, ConnectionId = Context.ConnectionId });
                ++i;
                UpdatePageUserList();
            }
            GetCurrentClientName();

            return base.OnConnected();
        }

        /// <summary>
        /// 重写断开方法,用户存在则删除用户
        /// </summary>
        /// <returns></returns>
        public override System.Threading.Tasks.Task OnDisconnected()
        {
            var user = list.Where(u => u.ConnectionId == Context.ConnectionId).FirstOrDefault();
            if (user != null)
            {
                list.Remove(user);
                UpdatePageUserList();
            }

            return base.OnDisconnected();
        }

        /// <summary>
        /// 更新页面用户列表,新增用户或者删除用户都需要更新一下
        /// </summary>
        public void UpdatePageUserList()
        {
            var json = JsonConvert.SerializeObject(list);
            Clients.All.refreshUserList(json);
        }

        /// <summary>
        /// 私聊对象方法
        /// </summary>
        /// <param name="ConnectionId"></param>
        public void StartChat(string ConnectionId, string content)
        {
            var user = list.Where(u => u.ConnectionId == ConnectionId).FirstOrDefault();

            //判断用户是否存在,存在则发送
            if (user != null)
            {
                //给指定用户发送,把自己的ID传过去用户找到当前哪个私聊对话框,因为可以打开很多个对话框
                Clients.Client(ConnectionId).sendMessage(content + " " + DateTime.Now, Context.ConnectionId);
                //给自己发送,把用户的ID传给自己找到当前哪个私聊对话框,因为可以打开很多个对话框
                Clients.Client(Context.ConnectionId).sendMessage(content + " " + DateTime.Now, ConnectionId);
            }
            else
            {
                Clients.Client(Context.ConnectionId).showMessage("该用户已离线");
            }
        }

        /// <summary>
        /// 得到当前客户端的名字
        /// </summary>
        public void GetCurrentClientName()
        {
            var user = list.Where(u => u.ConnectionId == Context.ConnectionId).FirstOrDefault();

            Clients.Client(Context.ConnectionId).showCurrentClient(user.Name);

        }

    }
}

客户端代码

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/jquery.signalR-2.0.0.js"></script>
    <!--这里要注意,这是虚拟目录,也就是你在OWIN Startup中注册的地址-->
    <script src="signalr/hubs"></script>
</head>
<body>
    <div><span>当前用户端名字:</span><span id="kkk"></span></div>
    <div style="width:200px;float:left;border:1px solid black;">
        <ul id="userList"></ul>
    </div>

    <script type="text/javascript">

        $(function () {
            //1.声明一个代理引用集线器,如果集线器没有取别名,则要小写$.connection.testHub;如果有别名则直接写别名就好了
            var chatClient = $.connection.testHHH;
            //注册显示信息方法
            chatClient.client.showMessage = function (msg) {
                alert(msg);
            }
            //注册获取当前客户端名字
            chatClient.client.showCurrentClient = function (name) {
                $("#kkk").html(name);
            }
            //注册刷新用户列表方法
            chatClient.client.refreshUserList = function (data) {
                var json = $.parseJSON(data);
                $("#userList").html("");
                for (var i = 0; i < json.length; i++) {
                    //动态加载内容到ul中
                    $("#userList").append($("<li>" + json[i].Name + " <input type='button' name='" + json[i].Name + "'  class='" + json[i].ConnectionId + "' onclick='privateChat(this)' value='与他私聊' /></li>"));
                }

            }

            //注册发送消息
            chatClient.client.sendMessage = function (msg, id) {

                $("#" + id + " ul").append($("<li>" + msg + "</li>"));
            }

            //3. 必须启动连接
            $.connection.hub.start().done(function () {

            });

        });

        function privateChat(btn) {
            var ConnectionId = $(btn).attr("class");
            var Name = $(btn).attr("name");

            if ($("#" + ConnectionId).length > 0) {
                alert("已打开对话窗口");
            }
            else {
                var str = "<div style='width:400px;float:left;border:1px solid black;' id='" + ConnectionId + "'><div>" +
            "私聊对象:<input type='text' name='name' value='" + Name + "' />" +
            "<div>" +
             "   <ul id='ul'>" +
             "       <li>开始群聊咯。。。。。。。。。。。。。</li>" +
              "  </ul>" +
              "  <input type='text' name='content'  /><input type='button' name='btn'  value='发送' onclick='sendMsg(this)' />" +
           " </div>" +
       " </div>" +
   " </div>";
                $("body").append($(str));

            }
        }

        function sendMsg(btn) {
            var connectionId = $(btn).parent().parent().parent().attr("id");//获取需要发送信息的员工连接ID
            var content = $(btn).siblings("input").val();//发送内容

            var chatClient = $.connection.testHHH; //因为集线程变量作用范围原因,和上面的在$(function(){})中写的chatClient不在一个范围内了,所以在这里重新获取一次才能够调用后台的方法
            chatClient.server.startChat(connectionId, content);
        }

    </script>
</body>
</html>

显示结果:

三、注意事项

代码连接:http://pan.baidu.com/s/1o7oNSue

SignalR2.0开发实例之——私聊的更多相关文章

  1. SignalR2.0开发实例之——设置时间、后台其他地方使用集线器、使用自己的连接ID

    一.连接的生命周期设置: 如下: // 该值表示连接在超时之前保持打开状态的时间长度. //默认为110秒 GlobalHost.Configuration.ConnectionTimeout = T ...

  2. SignalR2.0开发实例之——群发消息

    一.前言 ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相 ...

  3. SignalR2.0开发实例之——创建房间聊天

    SignalR作为一个强大的集线器,已经在hub里面集成了Gorups,也就是分组管理,使用方法如下: //作用:将连接ID加入某个组 //Context.ConnectionId 连接ID,每个页面 ...

  4. SignalR2.0开发实例之——负载均衡

    SignalR 2.0作为一个新的而且强大的通信工具,发布博客之后得到了很多人的支持,谢谢...也有人对性能和架设等问题提出了各种质疑..真的很感谢.. 我特意下载了SignalR 2.0的源码硬着头 ...

  5. 一篇对OAuth2.0开发实例的介绍

    今天看到了博友对SSO的文章,SSO单点登录的讲解突然想写一篇关于OAuth2.0用户授权的介绍. 应用场景:在APP或者网页接入一些第三方应用时,时长会需要用户登录另一个合作平台,比如QQ,微博,微 ...

  6. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)

    接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 bool PlaneWarGame::init() { bool bRet = fals ...

  7. 脑洞大开之采用HTML5+SignalR2.0(.Net)实现原生Web视频

    目录 对SignalR不了解的人可以直接移步下面的目录 SignalR系列目录 前言 - -,我又来了,今天废话不多说,我们直接来实现Web视频聊天. 采用的技术如下: HTML5 WebRTC Si ...

  8. 用SignalR 2.0开发客服系统[系列1:实现群发通讯]

    前言 交流群:195866844 先说一下我为什么会写这个博客吧,(首先说一下,我是一个小菜鸟,讲的不好请指导 - -,)  前段时间公司的项目涉及到在B/S上使用即时通讯,(其实就是做一个B/S的客 ...

  9. 用SignalR 2.0开发客服系统[系列2:实现聊天室]

    前言 交流群:195866844 上周发表了 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持.. 这周继续系列2,实现聊天室 ...

随机推荐

  1. 解决easyui datagrid加载数据时,checkbox列没有根据checkbox的值来确定是否选中

    背景:   昨天帮朋友做一个easyui datagrid的小实例时,才发现easyui datagrid的checkbox列,没有根据值为true或false来选中checkbox,当时感觉太让人失 ...

  2. python requests 基础学习

    首先,Python 标准库中的 urllib2 模块提供了你所需要的大多数 HTTP 功能,但是它的 API 不友好.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来 ...

  3. innerHTML的运用

    <!doctype html> <html> <style> li{float:left;margin:0 100px;color:red;} </style ...

  4. 比file_get_contents稳定的curl_get_contents

    相信使用过file_get_contents函数的朋友都知道,当获取的$url访问不了时,会导致页面漫长的等待,甚至还能导致PHP进程占用CPU达100%,因此这个函数就诞生了 分享一个实际在用的函数 ...

  5. Python交互模式下方向键出现乱码

    解决办法如下: 1.安装readline模块 readline库是bash shell用的库,包含许多功能,如命令行自动补全等. ubuntu下安装的命令:   sudo apt-get instal ...

  6. servlet中filter(过滤器)的学习使用

    servlet过滤器是小型的web组件,它能够处理传入的请求和传出的响应.Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理r ...

  7. Collection Views and Building Custom Layouts-备

    UICollectionView的结构回顾 首先回顾一下Collection View的构成,我们能看到的有三个部分: Cells Supplementary Views 追加视图 (类似Header ...

  8. 转:Node.js软肋之CPU密集型任务

    文章来自于:http://www.infoq.com/cn/articles/nodejs-weakness-cpu-intensive-tasks Node.js在官网上是这样定义的:“一个搭建在C ...

  9. 文件下载cordovaFileTransfer:cordova.file.documentsDirectory is null

    在Android平台上使用:$cordovaFileTransfer进行文件下载时提示:cordova.file.documentsDirectory is null,查了以下文档参照:http:// ...

  10. UML建模之时序图

    现在是二月,而且到如今你或许已经读到.或听到人们谈论UML 2.0 —— 包括若干进步的 UML 的新规范,所做的变化.考虑到新规范的重要性,我们也正在修改这个文章系列的基础,把我们的注意力从 OMG ...