SignalR2.0开发实例之——私聊

一、前言

继续上一章的补充,这章介绍使用私聊的功能。主要通过一个方法   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>
        public static int i = 1;

        /// <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

时间: 2024-11-08 22:49:45

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

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

一.前言 ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的. WebSockets是HTML5提供的新的API,可以在Web网页与服务器端间建立Socket连接,当WebSockets可用时(即浏览器支持Html5)SignalR使用WebSockets,当不支持时SignalR将使用其它技术来保证达到相同效果. Si

iOS OpenGL ES2.0 开发实例

本教程源码地址下载:https://github.com/wanglixin1999/HelloGL OpenGL ES 是可以在iphone上实现2D和3D图形编程的低级API. 如果你之前接触过 cocos2d,sparrow,corona,unity 这些框架,你会发现其实它们都是基于OpenGL上创建的. 多数程序员选择使用这些框架,而不是直接调用OpenGL,因为OpenGL实在是太难用了. 而这篇教程,就是为了让大家更好地入门而写的. 在这个系列的文章中,你可以通过一些实用又容易上手

ext 6.0开发实例二

由于Ext JS 6将原来的Ext JS和Sencha Touch合并为一个框架,因而在使用CMD来创建应用程序前,需要考虑清楚你是要创建一个通用应用程序,还是仅仅只是针对桌面或移动设备的应用程序. 要做这样的考量,是因为通用应用程序和比较单一的应用程序在开发上会有些小麻烦.这些小麻烦主要是因为Ext JS的自动加载机制造成的,有时候会很困扰人. Ext JS的自动加载机制是根据类名来划分目录兵加载脚本的,例如SimpelCMS.view.Main,如果没有自定义过SimpelCMS的路径指向,

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

在飞机大战游戏开发中遇到的问题和解决方法: 1.在添加菜单时,我要添加一个有背景的菜单,需要在菜单pMenu中添加一个图片精灵,结果编译过了但是运行出错,如下图: 查了很多资料,调试了很长时间,整个人都要崩溃了. 最后发现引擎中CCMenu::itemForTouch函数中有遍历子节点的行为,但是循环中没有判断子节点类型是否为CCMenuItem.如图:码,这样一来,加入到pMenu中的图片精灵被当作菜单项取了出来使用,导致报错.老版本的果然又不完善的地方,整个人都不好了...果断修改引擎里的源

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

接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 1 bool PlaneWarGame::init() 2 { 3 bool bRet = false; 4 do 5 { 6 CC_BREAK_IF(! CCLayer::init()); 7 8 _size = CCDirector::sharedDirector()->getWinSize(); 9 10 // 设置触摸可用 11 this->setIsTouchEnabled

Cocos2d-x 3.X手游开发实例详解

Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048.卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰然网创始人杨雍力荐) 于浩洋 著   ISBN 978-7-121-23998-4 2014年9月出版 定价:59.00元 356页 16开 编辑推荐 以Cocos2d-x V3.0为框架全面讲解手游开发的知识和方法 以热门游戏2048.卡牌为例,完整再现手游的开发过程 Cocos2d-x作者之一林

独家全功能USB2.0开发板,最强CY7C68013A-128核心板,超强资料不断提供更新服务

       学习USB开发再也不用买书啦,也不用花费重金去上培训班啦,IFLabs开创USB学习开发新模式,你所需要的知识.技术.范例.代码等等统统都在这里.IFLabs打造全网最丰富.最权威的USB开发平台和资料. 热卖的IFLabs精品USB2.0核心板套件再升级,全网独家推出最强.最全功能的Cypress USB 2.0 CY7C68013A-128AXC核心板开发板,全网最全配件和全网最全开发资料.只需这一次投入,即可实现USB接口开发的从入门到精通!并且有长期的全网最全开发手册更新支

Android手机拨打电话的开发实例

一部手机最常用的功能就是打电话和发短信了,在Android开发中我们如何通过程序拨打电话呢?本文就给出一个用Android手机拨打电话的简单的实例. 下面是开发此实例的具体步骤: 一.新建一个Android工程,命名为phoneCallDemo. 二.设计程序的界面,打开main.xml把内容修改如下: XML/HTML代码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and

JDBC - 开发实例 - MVC模式

JDBC - 开发实例 - MVC模式  1. 在web.xml中配置连接数据库的信息 web.xml: <context-param> <param-name>server</param-name> //主机名 <param-value>localhost</param-value> </context-param> <context-param> <param-name>db</param-name&